summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ApiDocs.bp1
-rw-r--r--ProtoLibraries.bp18
-rw-r--r--StubLibraries.bp10
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java2
-rw-r--r--boot/Android.bp8
-rw-r--r--cmds/bootanimation/BootAnimation.cpp10
-rw-r--r--core/api/current.txt23
-rw-r--r--core/api/module-lib-current.txt38
-rw-r--r--core/api/system-current.txt7
-rw-r--r--core/api/test-current.txt26
-rw-r--r--core/java/android/app/ActivityOptions.java14
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java71
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java42
-rw-r--r--core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java45
-rw-r--r--core/java/android/app/servertransaction/ActivityTransactionItem.java4
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java7
-rw-r--r--core/java/android/app/servertransaction/StartActivityItem.java4
-rw-r--r--core/java/android/content/Context.java6
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java2
-rw-r--r--core/java/android/content/pm/IPackageInstallerSession.aidl1
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl11
-rw-r--r--core/java/android/content/pm/PackageInstaller.java12
-rw-r--r--core/java/android/hardware/biometrics/BiometricFingerprintConstants.java29
-rw-r--r--core/java/android/hardware/camera2/params/DynamicRangeProfiles.java1
-rw-r--r--core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl7
-rw-r--r--core/java/android/inputmethodservice/IInputMethodWrapper.java36
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java17
-rw-r--r--core/java/android/inputmethodservice/NavigationBarController.java99
-rw-r--r--core/java/android/nfc/Tag.java10
-rw-r--r--core/java/android/os/ExternalVibration.java10
-rw-r--r--core/java/android/os/IpcDataCache.java364
-rw-r--r--core/java/android/os/Process.java76
-rw-r--r--core/java/android/os/UserManager.java16
-rw-r--r--core/java/android/os/storage/IStorageManager.aidl12
-rw-r--r--core/java/android/os/storage/StorageManager.java18
-rw-r--r--core/java/android/provider/Settings.java13
-rw-r--r--core/java/android/service/dreams/DreamService.java2
-rw-r--r--core/java/android/service/dreams/OWNERS5
-rw-r--r--core/java/android/util/NtpTrustedTime.java84
-rw-r--r--core/java/android/view/IWindowManager.aidl5
-rw-r--r--core/java/android/view/InputWindowHandle.java101
-rw-r--r--core/java/android/view/MotionEvent.java2
-rw-r--r--core/java/android/view/SurfaceView.java215
-rw-r--r--core/java/android/view/ViewConfiguration.java1
-rw-r--r--core/java/android/view/ViewRootImpl.java73
-rw-r--r--core/java/android/view/WindowManager.java57
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java32
-rw-r--r--core/java/android/view/inputmethod/InputMethod.java19
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java14
-rw-r--r--core/java/android/view/selectiontoolbar/SelectionToolbarManager.java2
-rw-r--r--core/java/android/webkit/WebSettings.java5
-rw-r--r--core/java/android/widget/RemoteViews.java8
-rw-r--r--core/java/android/widget/TextView.java5
-rw-r--r--core/java/android/widget/inline/InlineContentView.java5
-rw-r--r--core/java/android/window/SurfaceSyncer.java23
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java5
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java49
-rw-r--r--core/java/com/android/internal/net/VpnConfig.java7
-rw-r--r--core/java/com/android/internal/policy/TransitionAnimation.java4
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl2
-rw-r--r--core/java/com/android/internal/view/IInputMethod.aidl8
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp67
-rw-r--r--core/jni/android_hardware_input_InputWindowHandle.cpp104
-rw-r--r--core/jni/android_util_Process.cpp82
-rw-r--r--core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp4
-rw-r--r--core/proto/android/os/incident.proto4
-rw-r--r--core/proto/android/server/windowmanagerservice.proto1
-rw-r--r--core/proto/android/service/netstats.proto121
-rw-r--r--core/res/AndroidManifest.xml33
-rw-r--r--core/res/OWNERS4
-rw-r--r--core/res/res/anim-ldrtl/activity_close_enter.xml55
-rw-r--r--core/res/res/anim-ldrtl/activity_close_exit.xml55
-rw-r--r--core/res/res/anim-ldrtl/activity_open_enter.xml53
-rw-r--r--core/res/res/anim-ldrtl/activity_open_exit.xml54
-rw-r--r--core/res/res/drawable/ic_swap_horiz.xml28
-rw-r--r--core/res/res/layout/user_switching_dialog.xml7
-rw-r--r--core/res/res/values/config.xml9
-rw-r--r--core/res/res/values/ids.xml16
-rw-r--r--core/res/res/values/public.xml14
-rw-r--r--core/res/res/values/strings.xml24
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/res/raw/obb_enc_file100_orig1.obbbin275008 -> 0 bytes
-rw-r--r--core/tests/coretests/res/raw/obb_enc_file100_orig3.obbbin298560 -> 0 bytes
-rw-r--r--core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java2
-rw-r--r--core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java2
-rw-r--r--core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java2
-rw-r--r--core/tests/coretests/src/android/graphics/FontListParserTest.java21
-rw-r--r--core/tests/coretests/src/android/os/IpcDataCacheTest.java312
-rw-r--r--core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java26
-rw-r--r--core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java59
-rw-r--r--core/tests/coretests/src/android/view/MotionEventTest.java24
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java30
-rw-r--r--data/etc/privapp-permissions-platform.xml21
-rw-r--r--data/fonts/fonts.xml3
-rw-r--r--graphics/java/android/graphics/BLASTBufferQueue.java50
-rw-r--r--graphics/java/android/graphics/FontListParser.java5
-rw-r--r--graphics/java/android/graphics/RuntimeShader.java220
-rw-r--r--identity/java/android/security/identity/CredentialDataRequest.java28
-rw-r--r--identity/java/android/security/identity/PresentationSession.java3
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java6
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java)121
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java)30
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java60
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java55
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java74
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java96
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java36
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java33
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java150
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java98
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java2
-rw-r--r--libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml (renamed from packages/SystemUI/res/layout/communal_host_view.xml)12
-rw-r--r--libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java174
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java117
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java60
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java30
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java6
-rw-r--r--libs/hwui/Android.bp5
-rw-r--r--libs/storage/IMountService.cpp3
-rw-r--r--libs/storage/include/storage/IMountService.h4
-rw-r--r--media/java/android/media/AudioManager.java16
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl3
-rw-r--r--media/java/android/media/MediaRouter2.java892
-rw-r--r--media/java/android/media/NearbyDevice.java38
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppService.java2
-rw-r--r--media/jni/tuner/FilterClient.cpp1
-rw-r--r--native/android/storage_manager.cpp13
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_apps.xml34
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_notifications.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_storage.xml25
-rw-r--r--packages/CompanionDeviceManager/res/layout/activity_confirmation.xml5
-rw-r--r--packages/CompanionDeviceManager/res/layout/list_item_permission.xml55
-rw-r--r--packages/CompanionDeviceManager/res/values/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java64
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java19
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java128
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java7
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java10
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java2
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java14
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java16
-rw-r--r--packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java26
-rw-r--r--packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java4
-rw-r--r--packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java16
-rw-r--r--packages/SettingsLib/res/drawable/ic_account_circle.xml (renamed from packages/SystemUI/res/drawable/ic_account_circle.xml)0
-rw-r--r--packages/SettingsLib/res/drawable/ic_account_circle_filled.xml (renamed from packages/SystemUI/res/drawable/ic_account_circle_filled.xml)0
-rw-r--r--packages/SettingsLib/res/drawable/ic_add_supervised_user.xml (renamed from packages/SystemUI/res/drawable/ic_add_supervised_user.xml)0
-rw-r--r--packages/SettingsLib/res/drawable/user_avatar_bg.xml (renamed from packages/SystemUI/res/drawable/kg_bg_avatar.xml)2
-rw-r--r--packages/SettingsLib/res/values/colors.xml3
-rw-r--r--packages/SettingsLib/res/values/strings.xml4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java16
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java12
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java17
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java13
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java2
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt50
-rw-r--r--packages/SystemUI/proguard.flags8
-rw-r--r--packages/SystemUI/res/color/kg_user_avatar_frame.xml4
-rw-r--r--packages/SystemUI/res/drawable/user_switcher_icon_large.xml2
-rw-r--r--packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml11
-rw-r--r--packages/SystemUI/res/layout/media_output_dialog.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml3
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_section_header.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml39
-rw-r--r--packages/SystemUI/res/values-am/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml48
-rw-r--r--packages/SystemUI/res/values-as/strings.xml39
-rw-r--r--packages/SystemUI/res/values-az/strings.xml48
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml48
-rw-r--r--packages/SystemUI/res/values-be/strings.xml48
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml50
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml40
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml44
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml48
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml49
-rw-r--r--packages/SystemUI/res/values-da/strings.xml48
-rw-r--r--packages/SystemUI/res/values-de/strings.xml48
-rw-r--r--packages/SystemUI/res/values-el/strings.xml49
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml38
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml38
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml38
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml38
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml28
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml49
-rw-r--r--packages/SystemUI/res/values-es/strings.xml48
-rw-r--r--packages/SystemUI/res/values-et/strings.xml48
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml48
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml50
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml50
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml48
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml48
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml48
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml49
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml48
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml49
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml40
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml48
-rw-r--r--packages/SystemUI/res/values-in/strings.xml48
-rw-r--r--packages/SystemUI/res/values-is/strings.xml48
-rw-r--r--packages/SystemUI/res/values-it/strings.xml46
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml40
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml40
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml48
-rw-r--r--packages/SystemUI/res/values-km/strings.xml49
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml42
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml51
-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.xml48
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml49
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml40
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml40
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml40
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml48
-rw-r--r--packages/SystemUI/res/values-my/strings.xml50
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml40
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml49
-rw-r--r--packages/SystemUI/res/values-or/strings.xml39
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml48
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml48
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml49
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml49
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml49
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml49
-rw-r--r--packages/SystemUI/res/values-si/strings.xml48
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml40
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml40
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml48
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml48
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml48
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml48
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/dimens.xml46
-rw-r--r--packages/SystemUI/res/values-sw720dp-land/dimens.xml2
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml39
-rw-r--r--packages/SystemUI/res/values-te/strings.xml40
-rw-r--r--packages/SystemUI/res/values-th/strings.xml49
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml49
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml48
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml40
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml49
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml48
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml48
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml48
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml48
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml39
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml35
-rw-r--r--packages/SystemUI/res/values/strings.xml9
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java (renamed from packages/SystemUI/src/com/android/systemui/dagger/qualifiers/UiBackground.java)0
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java13
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt7
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt16
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButton.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java16
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java16
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/LatencyTester.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/Prefs.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java396
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java105
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java158
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java180
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java125
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java101
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java67
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java125
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt219
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt90
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt (renamed from startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql)24
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt65
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt351
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt110
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt82
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt152
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt101
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt163
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt128
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java (renamed from packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java)18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java294
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java (renamed from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java)16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java92
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java242
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java119
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java169
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java205
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java91
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java77
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java70
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt93
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt55
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt172
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt181
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt132
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt149
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt138
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java106
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java113
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java10
-rw-r--r--services/Android.bp3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java9
-rw-r--r--services/api/current.txt7
-rw-r--r--services/backup/backuplib/java/com/android/server/backup/TransportManager.java54
-rw-r--r--services/companion/TEST_MAPPING3
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/NetworkTimeUpdateService.java35
-rw-r--r--services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java39
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java51
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java76
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java16
-rw-r--r--services/core/java/com/android/server/am/AppExitInfoTracker.java1
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java44
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java39
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java3
-rw-r--r--services/core/java/com/android/server/am/PendingStartActivityUids.java5
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java5
-rw-r--r--services/core/java/com/android/server/am/UserController.java14
-rw-r--r--services/core/java/com/android/server/am/UserSwitchingDialog.java9
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java20
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java12
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java41
-rw-r--r--services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java41
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java12
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java8
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplayMapper.java59
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java17
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java5
-rw-r--r--services/core/java/com/android/server/infra/AbstractPerUserSystemService.java3
-rw-r--r--services/core/java/com/android/server/input/GestureMonitorSpyWindow.java10
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java18
-rw-r--r--services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java14
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java105
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodMenuController.java4
-rw-r--r--services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java159
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java4
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java25
-rw-r--r--services/core/java/com/android/server/notification/PermissionHelper.java29
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java6
-rw-r--r--services/core/java/com/android/server/notification/ZenModeFiltering.java69
-rw-r--r--services/core/java/com/android/server/pm/AppDataHelper.java3
-rw-r--r--services/core/java/com/android/server/pm/BackgroundDexOptService.java2
-rw-r--r--services/core/java/com/android/server/pm/Computer.java15
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java45
-rw-r--r--services/core/java/com/android/server/pm/DexOptHelper.java3
-rw-r--r--services/core/java/com/android/server/pm/DumpHelper.java25
-rw-r--r--services/core/java/com/android/server/pm/DynamicCodeLoggingService.java6
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java125
-rw-r--r--services/core/java/com/android/server/pm/InstallParams.java4
-rw-r--r--services/core/java/com/android/server/pm/Installer.java13
-rw-r--r--services/core/java/com/android/server/pm/IntentResolverInterceptor.java126
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java87
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerLocal.java (renamed from packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java)17
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerNative.java25
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java5177
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageRemovedInfo.java1
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java1
-rw-r--r--services/core/java/com/android/server/pm/PreferredActivityHelper.java3
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java7
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java30
-rw-r--r--services/core/java/com/android/server/pm/ScanResult.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java33
-rw-r--r--services/core/java/com/android/server/pm/SharedUidMigration.java105
-rw-r--r--services/core/java/com/android/server/pm/SharedUserSetting.java19
-rw-r--r--services/core/java/com/android/server/pm/TEST_MAPPING9
-rw-r--r--services/core/java/com/android/server/pm/UserDataPreparer.java7
-rw-r--r--services/core/java/com/android/server/pm/UserManagerInternal.java8
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java89
-rw-r--r--services/core/java/com/android/server/pm/VerificationParams.java9
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java10
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java8
-rw-r--r--services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java20
-rw-r--r--services/core/java/com/android/server/policy/KeyCombinationManager.java24
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyInternal.java17
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java72
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java18
-rw-r--r--services/core/java/com/android/server/power/ShutdownThread.java4
-rw-r--r--services/core/java/com/android/server/storage/DeviceStorageMonitorService.java15
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java12
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java98
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityInterceptorCallback.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java100
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecordInputSink.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartInterceptor.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java18
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java23
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java209
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowListenerController.java11
-rw-r--r--services/core/java/com/android/server/wm/DragState.java40
-rw-r--r--services/core/java/com/android/server/wm/InputConfigAdapter.java138
-rw-r--r--services/core/java/com/android/server/wm/InputConsumerImpl.java12
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java62
-rw-r--r--services/core/java/com/android/server/wm/InputWindowHandleWrapper.java65
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java6
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java7
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java168
-rw-r--r--services/core/java/com/android/server/wm/RunningTasks.java29
-rw-r--r--services/core/java/com/android/server/wm/Task.java26
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioner.java20
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioningController.java15
-rw-r--r--services/core/java/com/android/server/wm/Transition.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java61
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java33
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java46
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp3
-rw-r--r--services/core/jni/gnss/GnssMeasurementCallback.cpp38
-rw-r--r--services/core/jni/gnss/GnssMeasurementCallback.h11
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java63
-rw-r--r--services/java/com/android/server/SystemServer.java18
-rw-r--r--services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java84
-rw-r--r--services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java20
-rw-r--r--services/startop/Android.bp36
-rw-r--r--services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt22
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java62
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt18
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt5
-rw-r--r--services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java54
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java22
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java25
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java14
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java20
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java34
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java42
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java69
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/OWNERS1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java6
-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.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/StubTransaction.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java82
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java42
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java4
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java69
-rw-r--r--startop/iorap/Android.bp44
-rw-r--r--startop/iorap/TEST_MAPPING12
-rw-r--r--startop/iorap/functional_tests/Android.bp50
-rw-r--r--startop/iorap/functional_tests/AndroidManifest.xml38
-rw-r--r--startop/iorap/functional_tests/AndroidTest.xml70
-rw-r--r--startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java416
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java139
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java104
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java138
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java459
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java46
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java114
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java267
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java806
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java174
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java131
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/RequestId.java125
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java109
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java127
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/TaskResult.java130
-rw-r--r--startop/iorap/stress/Android.bp42
-rw-r--r--startop/iorap/stress/main_memory.cc126
-rw-r--r--startop/iorap/tests/Android.bp72
-rw-r--r--startop/iorap/tests/AndroidManifest.xml37
-rw-r--r--startop/iorap/tests/AndroidTest.xml66
-rw-r--r--startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt181
-rw-r--r--startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt137
-rw-r--r--startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt140
-rwxr-xr-xstartop/scripts/app_startup/analyze_metrics.py457
-rwxr-xr-xstartop/scripts/app_startup/app_startup_runner.py393
-rwxr-xr-xstartop/scripts/app_startup/app_startup_runner_test.py176
-rwxr-xr-xstartop/scripts/app_startup/force_compiler_filter143
-rwxr-xr-xstartop/scripts/app_startup/launch_application52
-rw-r--r--startop/scripts/app_startup/lib/adb_utils.py126
-rw-r--r--startop/scripts/app_startup/lib/adb_utils_test.py16
-rw-r--r--startop/scripts/app_startup/lib/app_runner.py266
-rw-r--r--startop/scripts/app_startup/lib/app_runner_test.py104
-rw-r--r--startop/scripts/app_startup/lib/args_utils.py77
-rw-r--r--startop/scripts/app_startup/lib/args_utils_test.py58
-rwxr-xr-xstartop/scripts/app_startup/lib/common198
-rw-r--r--startop/scripts/app_startup/lib/data_frame.py201
-rw-r--r--startop/scripts/app_startup/lib/data_frame_test.py128
-rw-r--r--startop/scripts/app_startup/lib/perfetto_trace_collector.py166
-rw-r--r--startop/scripts/app_startup/lib/perfetto_trace_collector_test.py101
-rwxr-xr-xstartop/scripts/app_startup/parse_metrics215
-rwxr-xr-xstartop/scripts/app_startup/query_compiler_filter.py232
-rwxr-xr-xstartop/scripts/app_startup/query_compiler_filter_test.py116
-rwxr-xr-xstartop/scripts/app_startup/run_app_with_prefetch487
-rwxr-xr-xstartop/scripts/app_startup/run_app_with_prefetch.py230
-rw-r--r--startop/scripts/app_startup/run_app_with_prefetch_test.py286
-rwxr-xr-xstartop/scripts/app_startup/unlock_screen22
-rwxr-xr-xstartop/scripts/iorap/analyze_prefetch_file.py168
-rwxr-xr-xstartop/scripts/iorap/collector403
-rwxr-xr-xstartop/scripts/iorap/common253
-rwxr-xr-xstartop/scripts/iorap/compile_handcrafted_file.py297
-rw-r--r--startop/scripts/iorap/compiler.py73
-rw-r--r--startop/scripts/iorap/compiler_device.py68
-rwxr-xr-xstartop/scripts/iorap/compiler_ri.py325
-rw-r--r--startop/scripts/iorap/compiler_test.py78
-rwxr-xr-xstartop/scripts/iorap/dump_compiled_pb38
-rwxr-xr-xstartop/scripts/iorap/dump_trace_pb38
-rw-r--r--startop/scripts/iorap/generated/TraceFile_pb2.py259
-rwxr-xr-xstartop/scripts/iorap/generated/codegen_protos35
-rw-r--r--startop/scripts/iorap/lib/inode2filename.py94
-rwxr-xr-xstartop/scripts/iorap/lib/inode2filename_test.py83
-rw-r--r--startop/scripts/iorap/lib/iorapd_utils.py175
-rwxr-xr-xstartop/scripts/iorap/pull_textcache24
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pbbin28375 -> 0 bytes
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/common_systrace5
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/common_textcache2
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/test_result_systrace748
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pbbin34 -> 0 bytes
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pbbin62 -> 0 bytes
-rw-r--r--startop/scripts/lib/cmd_utils.py184
-rw-r--r--startop/scripts/lib/logcat_utils.py104
-rw-r--r--startop/scripts/lib/logcat_utils_test.py88
-rw-r--r--startop/scripts/lib/print_utils.py67
-rw-r--r--startop/scripts/trace_analyzer/lib/trace2db.py355
-rwxr-xr-xstartop/scripts/trace_analyzer/lib/trace2db_test.py222
-rw-r--r--startop/scripts/trace_analyzer/queries_all.sql57
-rw-r--r--startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql44
-rw-r--r--startop/scripts/trace_analyzer/queries_block_launch.sql52
-rw-r--r--startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql101
-rw-r--r--startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql42
-rw-r--r--startop/scripts/trace_analyzer/queries_get_procs.sql30
-rw-r--r--startop/scripts/trace_analyzer/queries_get_ui_threads.sql88
-rw-r--r--startop/scripts/trace_analyzer/queries_mark_write_join.sql53
-rwxr-xr-xstartop/scripts/trace_analyzer/run-sql-queries79
-rw-r--r--startop/scripts/trace_analyzer/test_fixtures/common_systrace518
-rwxr-xr-xstartop/scripts/trace_analyzer/trace_analyzer42
-rwxr-xr-xstartop/scripts/trace_analyzer/trace_analyzer.py51
-rwxr-xr-xstartop/scripts/trace_analyzer/trace_analyzer_recursive78
-rw-r--r--startop/scripts/trace_analyzer/trace_analyzer_test.py66
-rw-r--r--telecomm/java/android/telecom/Call.java27
-rw-r--r--telecomm/java/android/telecom/CallAudioState.java19
-rw-r--r--telecomm/java/android/telecom/Connection.java21
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java5
-rw-r--r--telephony/java/android/telephony/data/DataServiceCallback.java12
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java20
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt9
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt49
-rw-r--r--tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java10
-rw-r--r--tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java4
-rw-r--r--tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java73
-rw-r--r--tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt10
-rw-r--r--tools/aapt/Android.bp10
-rw-r--r--tools/aapt2/ResourceParser.cpp7
-rwxr-xr-xtools/fonts/fontchain_linter.py7
707 files changed, 17011 insertions, 25137 deletions
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 7f5d4a3fd504..038ee6501ded 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -81,7 +81,6 @@ stubs_defaults {
":framework-adservices-sources",
":framework-appsearch-sources",
- ":framework-auxiliary-sources",
":framework-connectivity-sources",
":framework-bluetooth-sources",
":framework-connectivity-tiramisu-updatable-sources",
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
index db5ba2fd031f..0f3ea0ca298f 100644
--- a/ProtoLibraries.bp
+++ b/ProtoLibraries.bp
@@ -33,13 +33,14 @@ gensrcs {
"&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
":libtombstone_proto-src",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
output_extension: "srcjar",
}
@@ -63,12 +64,13 @@ gensrcs {
" $(in)",
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
output_extension: "proto.h",
@@ -78,6 +80,7 @@ gensrcs {
java_library_host {
name: "platformprotos",
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
@@ -87,7 +90,7 @@ java_library_host {
"cmds/statsd/src/**/*.proto",
"core/proto/**/*.proto",
"libs/incident/proto/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
proto: {
include_dirs: [
@@ -117,12 +120,13 @@ java_library {
],
sdk_version: "9",
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
// Protos have lots of MissingOverride and similar.
errorprone: {
@@ -139,12 +143,13 @@ java_library {
},
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
exclude_srcs: [
"core/proto/android/privacy.proto",
@@ -176,11 +181,12 @@ cc_defaults {
],
srcs: [
+ ":framework-connectivity-protos",
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
"core/proto/**/*.proto",
- ":service-permission-protos",
+ ":service-permission-streaming-proto-sources",
],
}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index fef95e813ec7..32101c791242 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -208,6 +208,16 @@ droidstubs {
/////////////////////////////////////////////////////////////////////
java_defaults {
+ name: "android.jar_defaults",
+ sdk_version: "none",
+ system_modules: "none",
+ java_version: "1.8",
+ compile_dex: true,
+ defaults_visibility: ["//visibility:private"],
+ visibility: ["//visibility:public"],
+}
+
+java_defaults {
name: "android-non-updatable_defaults_stubs_current",
libs: ["stub-annotations"],
static_libs: ["framework-res-package-jar"], // Export package of framework-res
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
index 37b0aa8f4862..8a64238f1f17 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
@@ -103,7 +103,7 @@ class DeviceIdleModifier extends Modifier {
mIrs.onDeviceStateChanged();
}
} else if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
- if (mDeviceIdle != mPowerManager.isLightDeviceIdleMode()) {
+ if (mDeviceLightIdle != mPowerManager.isLightDeviceIdleMode()) {
mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
mIrs.onDeviceStateChanged();
}
diff --git a/boot/Android.bp b/boot/Android.bp
index 90c3b9c467f2..5b265a5dc9de 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -60,10 +60,6 @@ platform_bootclasspath {
module: "art-bootclasspath-fragment",
},
{
- apex: "com.android.auxiliary",
- module: "com.android.auxiliary-bootclasspath-fragment",
- },
- {
apex: "com.android.bluetooth",
module: "com.android.bluetooth-bootclasspath-fragment",
},
@@ -108,10 +104,6 @@ platform_bootclasspath {
module: "com.android.sdkext-bootclasspath-fragment",
},
{
- apex: "com.android.supplementalprocess",
- module: "com.android.supplementalprocess-bootclasspath-fragment",
- },
- {
apex: "com.android.tethering",
module: "com.android.tethering-bootclasspath-fragment",
},
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 1f4a64f5c7f1..f9317eba4e27 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -764,6 +764,7 @@ bool BootAnimation::threadLoop() {
// We have no bootanimation file, so we use the stock android logo
// animation.
if (mZipFileName.isEmpty()) {
+ ALOGD("No animation file");
result = android();
} else {
result = movie();
@@ -1476,6 +1477,10 @@ bool BootAnimation::playAnimation(const Animation& animation) {
part.backgroundColor[2],
1.0f);
+ ALOGD("Playing files = %s/%s, Requested repeat = %d, playUntilComplete = %s",
+ animation.fileName.string(), part.path.string(), part.count,
+ part.playUntilComplete ? "true" : "false");
+
// For the last animation, if we have progress indicator from
// the system, display it.
int currentProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);
@@ -1609,6 +1614,9 @@ bool BootAnimation::playAnimation(const Animation& animation) {
}
}
+ ALOGD("%sAnimationShownTiming End time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+ elapsedRealtime());
+
return true;
}
@@ -1684,6 +1692,8 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn) {
return nullptr;
}
+ ALOGD("%s is loaded successfully", fn.string());
+
Animation *animation = new Animation;
animation->fileName = fn;
animation->zip = zip;
diff --git a/core/api/current.txt b/core/api/current.txt
index 3e227e967c56..542221c3fcc9 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8,6 +8,9 @@ package android {
public static final class Manifest.permission {
ctor public Manifest.permission();
field public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
+ field public static final String ACCESS_ADSERVICES_ATTRIBUTION = "android.permission.ACCESS_ADSERVICES_ATTRIBUTION";
+ field public static final String ACCESS_ADSERVICES_CUSTOM_AUDIENCES = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES";
+ field public static final String ACCESS_ADSERVICES_TOPICS = "android.permission.ACCESS_ADSERVICES_TOPICS";
field public static final String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
field public static final String ACCESS_BLOBS_ACROSS_USERS = "android.permission.ACCESS_BLOBS_ACROSS_USERS";
field public static final String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
@@ -17,7 +20,6 @@ package android {
field public static final String ACCESS_MEDIA_LOCATION = "android.permission.ACCESS_MEDIA_LOCATION";
field public static final String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
field public static final String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
- field public static final String ACCESS_SUPPLEMENTAL_APIS = "android.permission.ACCESS_SUPPLEMENTAL_APIS";
field public static final String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
field public static final String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
field public static final String ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION";
@@ -979,8 +981,8 @@ package android {
field public static final int left = 16843181; // 0x10101ad
field public static final int letterSpacing = 16843958; // 0x10104b6
field public static final int level = 16844032; // 0x1010500
- field public static final int lineBreakStyle = 16844365; // 0x101064d
- field public static final int lineBreakWordStyle = 16844366; // 0x101064e
+ field public static final int lineBreakStyle;
+ field public static final int lineBreakWordStyle;
field public static final int lineHeight = 16844159; // 0x101057f
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -2094,12 +2096,8 @@ package android {
field public static final int accessibilityActionScrollUp = 16908344; // 0x1020038
field public static final int accessibilityActionSetProgress = 16908349; // 0x102003d
field public static final int accessibilityActionShowOnScreen = 16908342; // 0x1020036
- field public static final int accessibilityActionShowSuggestions;
+ field public static final int accessibilityActionShowTextSuggestions;
field public static final int accessibilityActionShowTooltip = 16908356; // 0x1020044
- field public static final int accessibilityActionSwipeDown;
- field public static final int accessibilityActionSwipeLeft;
- field public static final int accessibilityActionSwipeRight;
- field public static final int accessibilityActionSwipeUp;
field public static final int accessibilitySystemActionBack = 16908363; // 0x102004b
field public static final int accessibilitySystemActionHome = 16908364; // 0x102004c
field public static final int accessibilitySystemActionLockScreen = 16908370; // 0x1020052
@@ -40022,7 +40020,6 @@ package android.telecom {
field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
field public static final int PROPERTY_RTT = 1024; // 0x400
field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
- field public static final int PROPERTY_TETHERED_CALL = 32768; // 0x8000
field public static final int PROPERTY_VOIP_AUDIO_MODE = 4096; // 0x1000
field public static final int PROPERTY_WIFI = 8; // 0x8
}
@@ -40051,7 +40048,6 @@ package android.telecom {
field @NonNull public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR;
field public static final int ROUTE_BLUETOOTH = 2; // 0x2
field public static final int ROUTE_EARPIECE = 1; // 0x1
- field public static final int ROUTE_EXTERNAL = 16; // 0x10
field public static final int ROUTE_SPEAKER = 8; // 0x8
field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4
field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
@@ -40326,7 +40322,6 @@ package android.telecom {
field public static final int PROPERTY_IS_RTT = 256; // 0x100
field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1024; // 0x400
field public static final int PROPERTY_SELF_MANAGED = 128; // 0x80
- field public static final int PROPERTY_TETHERED_CALL = 16384; // 0x4000
field public static final int PROPERTY_WIFI = 8; // 0x8
field public static final int STATE_ACTIVE = 4; // 0x4
field public static final int STATE_DIALING = 3; // 0x3
@@ -51934,12 +51929,8 @@ package android.view.accessibility {
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_SELECTION;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
- field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_SUGGESTIONS;
+ field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TEXT_SUGGESTIONS;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TOOLTIP;
- field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_DOWN;
- field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_LEFT;
- field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_RIGHT;
- field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_UP;
field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> CREATOR;
}
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 70a61df221eb..241e5c8d97c4 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -20,10 +20,6 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
}
- public class ActivityOptions {
- method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle);
- }
-
public class AppOpsManager {
field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
}
@@ -54,22 +50,6 @@ package android.app {
method public void onCanceled(@NonNull android.app.PendingIntent);
}
- public class PropertyInvalidatedCache<Query, Result> {
- ctor public PropertyInvalidatedCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.app.PropertyInvalidatedCache.QueryHandler<Query,Result>);
- method public final void disableForCurrentProcess();
- method public final void invalidateCache();
- method public static void invalidateCache(@NonNull String, @NonNull String);
- method @Nullable public final Result query(@NonNull Query);
- field public static final String MODULE_BLUETOOTH = "bluetooth";
- field public static final String MODULE_TELEPHONY = "telephony";
- }
-
- public abstract static class PropertyInvalidatedCache.QueryHandler<Q, R> {
- ctor public PropertyInvalidatedCache.QueryHandler();
- method @Nullable public abstract R apply(@NonNull Q);
- method public boolean shouldBypassCache(@NonNull Q);
- }
-
public class StatusBarManager {
method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean);
}
@@ -358,13 +338,29 @@ package android.os {
field public static final int DEVICE_INITIAL_SDK_INT;
}
+ public class IpcDataCache<Query, Result> {
+ ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>);
+ method public void disableForCurrentProcess();
+ method public static void disableForCurrentProcess(@NonNull String);
+ method public void invalidateCache();
+ method public static void invalidateCache(@NonNull String, @NonNull String);
+ method @Nullable public Result query(@NonNull Query);
+ field public static final String MODULE_BLUETOOTH = "bluetooth";
+ }
+
+ public abstract static class IpcDataCache.QueryHandler<Q, R> {
+ ctor public IpcDataCache.QueryHandler();
+ method @Nullable public abstract R apply(@NonNull Q);
+ method public boolean shouldBypassCache(@NonNull Q);
+ }
+
public interface Parcelable {
method public default int getStability();
}
public class Process {
+ method public static final int getAppUidForSdkSandboxUid(int);
method public static final boolean isSdkSandboxUid(int);
- method public static final int toAppUid(int);
method public static final int toSdkSandboxUid(int);
field public static final int NFC_UID = 1027; // 0x403
field public static final int VPN_UID = 1016; // 0x3f8
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c033ea57c1a0..5a6e8ee22128 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -234,6 +234,7 @@ package android {
field public static final String POWER_SAVER = "android.permission.POWER_SAVER";
field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
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 public static final String QUERY_USERS = "android.permission.QUERY_USERS";
@@ -468,6 +469,7 @@ package android.app {
method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
method @Deprecated public boolean isBackgroundVisibleBehind();
method @Deprecated public void onBackgroundVisibleBehindChanged(boolean);
+ method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityAsUser(@NonNull android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, int, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, @NonNull String, int, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
@@ -1100,7 +1102,7 @@ package android.app.admin {
method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long);
method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean packageHasActiveAdmins(String);
- method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, android.Manifest.permission.PROVISION_DEMO_DEVICE}) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetDrawables(@NonNull String[]);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetStrings(@NonNull String[]);
method @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
@@ -1253,6 +1255,7 @@ package android.app.admin {
method @Nullable public java.util.Locale getLocale();
method @NonNull public String getOwnerName();
method @Nullable public String getTimeZone();
+ method public boolean isDemoDevice();
method public boolean isLeaveAllSystemAppsEnabled();
method public void writeToParcel(@NonNull android.os.Parcel, @Nullable int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FullyManagedDeviceProvisioningParams> CREATOR;
@@ -1263,6 +1266,7 @@ package android.app.admin {
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams build();
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setAdminExtras(@NonNull android.os.PersistableBundle);
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setCanDeviceOwnerGrantSensorsPermissions(boolean);
+ method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setDemoDevice(boolean);
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLeaveAllSystemAppsEnabled(boolean);
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocalTime(long);
method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocale(@Nullable java.util.Locale);
@@ -2944,7 +2948,6 @@ package android.content {
method public void sendBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable android.app.BroadcastOptions);
method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
field public static final String AMBIENT_CONTEXT_SERVICE = "ambient_context";
field public static final String APP_HIBERNATION_SERVICE = "app_hibernation";
field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4f319fb20745..abfeae9b285e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -154,7 +154,6 @@ package android.app {
}
public class ActivityOptions {
- method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle);
method public boolean isEligibleForLegacyPermissionPrompt();
method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
method @NonNull @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) public static android.app.ActivityOptions makeCustomTaskAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
@@ -374,16 +373,17 @@ package android.app {
public class PropertyInvalidatedCache<Query, Result> {
ctor public PropertyInvalidatedCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.app.PropertyInvalidatedCache.QueryHandler<Query,Result>);
method @NonNull public static String createPropertyName(@NonNull String, @NonNull String);
- method public final void disableForCurrentProcess();
+ method public void disableForCurrentProcess();
+ method public static void disableForCurrentProcess(@NonNull String);
method public static void disableForTestMode();
method public final void disableInstance();
method public final void disableSystemWide();
method public final void forgetDisableLocal();
method public boolean getDisabledState();
- method public final void invalidateCache();
+ method public void invalidateCache();
method public static void invalidateCache(@NonNull String, @NonNull String);
method public final boolean isDisabled();
- method @Nullable public final Result query(@NonNull Query);
+ method @Nullable public Result query(@NonNull Query);
method public static void setTestMode(boolean);
method public void testPropertyName();
field public static final String MODULE_BLUETOOTH = "bluetooth";
@@ -1466,6 +1466,7 @@ package android.media {
method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioTrack getCallUplinkInjectionAudioTrack(@NonNull android.media.AudioFormat);
method @Nullable public static android.media.AudioDeviceInfo getDeviceInfoFromType(int);
method @IntRange(from=0) @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public long getFadeOutDurationOnFocusLossMillis(@NonNull android.media.AudioAttributes);
+ method @Nullable public static String getHalVersion();
method public static final int[] getPublicStreamTypes();
method @NonNull public java.util.List<java.lang.Integer> getReportedSurroundFormats();
method public int getStreamMinVolumeInt(int);
@@ -1726,6 +1727,19 @@ package android.os {
method @NonNull public static byte[] digest(@NonNull java.io.InputStream, @NonNull String) throws java.io.IOException, java.security.NoSuchAlgorithmException;
}
+ public class IpcDataCache<Query, Result> extends android.app.PropertyInvalidatedCache<Query,Result> {
+ ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>);
+ method public static void disableForCurrentProcess(@NonNull String);
+ method public static void invalidateCache(@NonNull String, @NonNull String);
+ field public static final String MODULE_BLUETOOTH = "bluetooth";
+ field public static final String MODULE_SYSTEM = "system_server";
+ field public static final String MODULE_TEST = "test";
+ }
+
+ public abstract static class IpcDataCache.QueryHandler<Q, R> extends android.app.PropertyInvalidatedCache.QueryHandler<Q,R> {
+ ctor public IpcDataCache.QueryHandler();
+ }
+
public final class MessageQueue {
method public int postSyncBarrier();
method public void removeSyncBarrier(int);
@@ -1777,7 +1791,9 @@ package android.os {
}
public class Process {
+ method public static final int getAppUidForSdkSandboxUid(int);
method public static final int getThreadScheduler(int) throws java.lang.IllegalArgumentException;
+ method public static final boolean isSdkSandboxUid(int);
method public static final int toSdkSandboxUid(int);
field public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; // 0x15f90
field public static final int FIRST_ISOLATED_UID = 99000; // 0x182b8
@@ -2161,6 +2177,7 @@ package android.provider {
field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
field public static final String SHOW_FIRST_CRASH_DIALOG = "show_first_crash_dialog";
+ field public static final String STYLUS_HANDWRITING_ENABLED = "stylus_handwriting_enabled";
field public static final String USER_DISABLED_HDR_FORMATS = "user_disabled_hdr_formats";
field public static final String USER_PREFERRED_REFRESH_RATE = "user_preferred_refresh_rate";
field public static final String USER_PREFERRED_RESOLUTION_HEIGHT = "user_preferred_resolution_height";
@@ -2874,6 +2891,7 @@ package android.view {
method public static int getHoverTooltipHideTimeout();
method public static int getHoverTooltipShowTimeout();
method public static int getLongPressTooltipHideTimeout();
+ method public int getPreferKeepClearForFocusDelay();
}
public class ViewDebug {
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 87ac6cb1fe4c..0178fa143445 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1421,17 +1421,9 @@ public class ActivityOptions extends ComponentOptions {
return mRemoteTransition;
}
- /**
- * Creates an ActivityOptions from the Bundle generated from {@link ActivityOptions#toBundle()}.
- * Returns an instance of ActivityOptions populated with options with known keys from the
- * provided Bundle, stripping out unknown entries.
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @TestApi
- @NonNull
- public static ActivityOptions fromBundle(@NonNull Bundle bOptions) {
- return new ActivityOptions(bOptions);
+ /** @hide */
+ public static ActivityOptions fromBundle(Bundle bOptions) {
+ return bOptions != null ? new ActivityOptions(bOptions) : null;
}
/** @hide */
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index a82ecce2dc04..4fbe232556ed 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -116,7 +116,7 @@ interface INotificationManager
ParceledListSlice getNotificationChannelGroups(String pkg);
boolean onlyHasDefaultChannel(String pkg, int uid);
boolean areChannelsBypassingDnd();
- ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
+ ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int uid);
boolean isPackagePaused(String pkg);
void deleteNotificationHistoryItem(String pkg, int uid, long postedTime);
boolean isPermissionFixed(String pkg, int userId);
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 2f202d95e0e3..df7bf7b94700 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -18,7 +18,6 @@ package android.app;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Handler;
import android.os.Looper;
@@ -137,6 +136,26 @@ import java.util.concurrent.atomic.AtomicLong;
* With this cache, clients perform a binder call to birthdayd if asking for a user's birthday
* for the first time; on subsequent queries, we return the already-known Birthday object.
*
+ * The second parameter to the IpcDataCache constructor is a string that identifies the "module"
+ * that owns the cache. There are some well-known modules (such as {@code MODULE_SYSTEM} but any
+ * string is permitted. The third parameters is the name of the API being cached; this, too, can
+ * any value. The fourth is the name of the cache. The cache is usually named after th API.
+ * Some things you must know about the three strings:
+ * <list>
+ * <ul> The system property that controls the cache is named {@code cache_key.<module>.<api>}.
+ * Usually, the SELinux rules permit a process to write a system property (and therefore
+ * invalidate a cache) based on the wildcard {@code cache_key.<module>.*}. This means that
+ * although the cache can be constructed with any module string, whatever string is chosen must be
+ * consistent with the SELinux configuration.
+ * <ul> The API name can be any string of alphanumeric characters. All caches with the same API
+ * are invalidated at the same time. If a server supports several caches and all are invalidated
+ * in common, then it is most efficient to assign the same API string to every cache.
+ * <ul> The cache name can be any string. In debug output, the name is used to distiguish between
+ * caches with the same API name. The cache name is also used when disabling caches in the
+ * current process. So, invalidation is based on the module+api but disabling (which is generally
+ * a once-per-process operation) is based on the cache name.
+ * </list>
+ *
* User birthdays do occasionally change, so we have to modify the server to invalidate this
* cache when necessary. That invalidation code looks like this:
*
@@ -192,25 +211,23 @@ import java.util.concurrent.atomic.AtomicLong;
* <pre>
* public class ActivityThread {
* ...
- * private static final int BDAY_CACHE_MAX = 8; // Maximum birthdays to cache
- * private static final String BDAY_CACHE_KEY = "cache_key.birthdayd";
- * private final PropertyInvalidatedCache&lt;Integer, Birthday%&gt; mBirthdayCache = new
- * PropertyInvalidatedCache&lt;Integer, Birthday%&gt;(BDAY_CACHE_MAX, BDAY_CACHE_KEY) {
- * {@literal @}Override
- * protected Birthday recompute(Integer userId) {
- * return GetService("birthdayd").getUserBirthday(userId);
- * }
- * {@literal @}Override
- * protected boolean bypass(Integer userId) {
- * return userId == NEXT_BIRTHDAY;
- * }
- * };
+ * private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ * new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ * {@literal @}Override
+ * public Birthday apply(Integer) {
+ * return GetService("birthdayd").getUserBirthday(userId);
+ * }
+ * {@literal @}Override
+ * public boolean shouldBypassQuery(Integer userId) {
+ * return userId == NEXT_BIRTHDAY;
+ * }
+ * };
* ...
* }
* </pre>
*
- * If the {@code bypass()} method returns true then the cache is not used for that
- * particular query. The {@code bypass()} method is not abstract and the default
+ * If the {@code shouldBypassQuery()} method returns true then the cache is not used for that
+ * particular query. The {@code shouldBypassQuery()} method is not abstract and the default
* implementation returns false.
*
* For security, there is a allowlist of processes that are allowed to invalidate a cache.
@@ -231,14 +248,12 @@ import java.util.concurrent.atomic.AtomicLong;
* @param <Result> The class holding cache entries; use a boxed primitive if possible
* @hide
*/
-@SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
public class PropertyInvalidatedCache<Query, Result> {
/**
* This is a configuration class that customizes a cache instance.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
public static abstract class QueryHandler<Q,R> {
/**
@@ -285,7 +300,6 @@ public class PropertyInvalidatedCache<Query, Result> {
* The module used for bluetooth caches.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
public static final String MODULE_BLUETOOTH = "bluetooth";
@@ -533,7 +547,6 @@ public class PropertyInvalidatedCache<Query, Result> {
* @param computer The code to compute values that are not in the cache.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
public PropertyInvalidatedCache(int maxEntries, @NonNull String module, @NonNull String api,
@NonNull String cacheName, @NonNull QueryHandler<Query, Result> computer) {
@@ -792,7 +805,7 @@ public class PropertyInvalidatedCache<Query, Result> {
* TODO(216112648) Remove this in favor of disableForCurrentProcess().
* @hide
*/
- public final void disableLocal() {
+ public void disableLocal() {
disableForCurrentProcess();
}
@@ -802,12 +815,17 @@ public class PropertyInvalidatedCache<Query, Result> {
* property.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
- public final void disableForCurrentProcess() {
+ public void disableForCurrentProcess() {
disableLocal(mCacheName);
}
+ /** @hide */
+ @TestApi
+ public static void disableForCurrentProcess(@NonNull String cacheName) {
+ disableLocal(cacheName);
+ }
+
/**
* Return whether a cache instance is disabled.
* @hide
@@ -821,9 +839,8 @@ public class PropertyInvalidatedCache<Query, Result> {
* Get a value from the cache or recompute it.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
- public final @Nullable Result query(@NonNull Query query) {
+ public @Nullable Result query(@NonNull Query query) {
// Let access to mDisabled race: it's atomic anyway.
long currentNonce = (!isDisabled()) ? getCurrentNonce() : NONCE_DISABLED;
if (bypass(query)) {
@@ -964,9 +981,8 @@ public class PropertyInvalidatedCache<Query, Result> {
* PropertyInvalidatedCache is keyed on a particular property value.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
- public final void invalidateCache() {
+ public void invalidateCache() {
invalidateCache(mPropertyName);
}
@@ -974,7 +990,6 @@ public class PropertyInvalidatedCache<Query, Result> {
* Invalidate caches in all processes that are keyed for the module and api.
* @hide
*/
- @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
@TestApi
public static void invalidateCache(@NonNull String module, @NonNull String api) {
invalidateCache(createPropertyName(module, api));
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 54ad43cfe10e..8d4e0d6c1f42 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1413,6 +1413,9 @@ public class DevicePolicyManager {
* admin app when performing the admin-integrated provisioning flow as a result of the
* {@link #ACTION_GET_PROVISIONING_MODE} activity.
*
+ * <p>This extra may also be provided to the admin app via an intent extra for {@link
+ * #ACTION_GET_PROVISIONING_MODE}.
+ *
* @see #ACTION_GET_PROVISIONING_MODE
*/
public static final String EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT =
@@ -3062,6 +3065,8 @@ public class DevicePolicyManager {
* <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</li>
* <li>{@link #EXTRA_PROVISIONING_IMEI}</li>
* <li>{@link #EXTRA_PROVISIONING_SERIAL_NUMBER}</li>
+ * <li>{@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES}</li>
+ * <li>{@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT}</li>
* </ul>
*
* <p>The target activity should return one of the following values in
@@ -3085,8 +3090,22 @@ public class DevicePolicyManager {
* activity, along with the values of the {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE} extra
* that are already supplied to this activity.
*
- * @see #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION
- * @see #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED
+ * <p>Other extras the target activity may include in the intent result:
+ * <ul>
+ * <li>{@link #EXTRA_PROVISIONING_DISCLAIMERS}</li>
+ * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}</li>
+ * <li>{@link #EXTRA_PROVISIONING_KEEP_SCREEN_ON}</li>
+ * <li>{@link #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION} for work profile
+ * provisioning</li>
+ * <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED} for work profile
+ * provisioning</li>
+ * <li>{@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT} for fully-managed
+ * device provisioning</li>
+ * <li>{@link #EXTRA_PROVISIONING_LOCALE} for fully-managed device provisioning</li>
+ * <li>{@link #EXTRA_PROVISIONING_LOCAL_TIME} for fully-managed device provisioning</li>
+ * <li>{@link #EXTRA_PROVISIONING_TIME_ZONE} for fully-managed device provisioning</li>
+ * </ul>
+ *
* @see #ACTION_ADMIN_POLICY_COMPLIANCE
*/
public static final String ACTION_GET_PROVISIONING_MODE =
@@ -14776,17 +14795,20 @@ public class DevicePolicyManager {
* <p>The method {@link #checkProvisioningPrecondition} must be returning {@link #STATUS_OK}
* before calling this method.
*
+ * <p>Holders of {@link android.Manifest.permission#PROVISION_DEMO_DEVICE} can call this API
+ * only if {@link FullyManagedDeviceProvisioningParams#isDemoDevice()} is {@code true}.</p>
+ *
* @param provisioningParams Params required to provision a fully managed device,
* see {@link FullyManagedDeviceProvisioningParams}.
*
- * @throws SecurityException if the caller does not hold
- * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}.
* @throws ProvisioningException if an error occurred during provisioning.
*
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
+ android.Manifest.permission.PROVISION_DEMO_DEVICE})
public void provisionFullyManagedDevice(
@NonNull FullyManagedDeviceProvisioningParams provisioningParams)
throws ProvisioningException {
@@ -15643,7 +15665,9 @@ public class DevicePolicyManager {
}
/**
- * Returns a boolean for whether the DPC has been downloaded during provisioning.
+ * Returns a boolean for whether the DPC
+ * (Device Policy Controller, the agent responsible for enforcing policy)
+ * has been downloaded during provisioning.
*
* <p>If true is returned, then any attempts to begin setup again should result in factory reset
*
@@ -15664,9 +15688,11 @@ public class DevicePolicyManager {
}
/**
- * Use to indicate that the DPC has or has not been downloaded during provisioning.
+ * Indicates that the DPC (Device Policy Controller, the agent responsible for enforcing policy)
+ * has or has not been downloaded during provisioning.
*
- * @param downloaded {@code true} if the dpc has been downloaded during provisioning. false otherwise.
+ * @param downloaded {@code true} if the dpc has been downloaded during provisioning.
+ * {@code false} otherwise.
*
* @hide
*/
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
index 1f7ae4ad35de..49992452df86 100644
--- a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
@@ -26,6 +26,7 @@ import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import android.provider.Settings;
import android.stats.devicepolicy.DevicePolicyEnums;
import java.util.Locale;
@@ -44,6 +45,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
"CAN_DEVICE_OWNER_GRANT_SENSOR_PERMISSIONS";
private static final String TIME_ZONE_PROVIDED_PARAM = "TIME_ZONE_PROVIDED";
private static final String LOCALE_PROVIDED_PARAM = "LOCALE_PROVIDED";
+ private static final String DEMO_DEVICE = "DEMO_DEVICE";
@NonNull private final ComponentName mDeviceAdminComponentName;
@NonNull private final String mOwnerName;
@@ -54,6 +56,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
@Nullable private final Locale mLocale;
private final boolean mDeviceOwnerCanGrantSensorsPermissions;
@NonNull private final PersistableBundle mAdminExtras;
+ private final boolean mDemoDevice;
+
private FullyManagedDeviceProvisioningParams(
@NonNull ComponentName deviceAdminComponentName,
@@ -63,7 +67,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
long localTime,
@Nullable @SuppressLint("UseIcu") Locale locale,
boolean deviceOwnerCanGrantSensorsPermissions,
- @NonNull PersistableBundle adminExtras) {
+ @NonNull PersistableBundle adminExtras,
+ boolean demoDevice) {
this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
this.mOwnerName = requireNonNull(ownerName);
this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
@@ -73,6 +78,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
this.mDeviceOwnerCanGrantSensorsPermissions =
deviceOwnerCanGrantSensorsPermissions;
this.mAdminExtras = adminExtras;
+ this.mDemoDevice = demoDevice;
}
private FullyManagedDeviceProvisioningParams(
@@ -83,7 +89,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
long localTime,
@Nullable String localeStr,
boolean deviceOwnerCanGrantSensorsPermissions,
- @Nullable PersistableBundle adminExtras) {
+ @Nullable PersistableBundle adminExtras,
+ boolean demoDevice) {
this(deviceAdminComponentName,
ownerName,
leaveAllSystemAppsEnabled,
@@ -91,7 +98,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
localTime,
getLocale(localeStr),
deviceOwnerCanGrantSensorsPermissions,
- adminExtras);
+ adminExtras,
+ demoDevice);
}
@Nullable
@@ -166,6 +174,14 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
}
/**
+ * @return true if this device is being setup as a retail demo device, see
+ * {@link Settings.Global#DEVICE_DEMO_MODE}.
+ */
+ public boolean isDemoDevice() {
+ return mDemoDevice;
+ }
+
+ /**
* Logs the provisioning params using {@link DevicePolicyEventLogger}.
*
* @hide
@@ -178,6 +194,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
mDeviceOwnerCanGrantSensorsPermissions);
logParam(callerPackage, TIME_ZONE_PROVIDED_PARAM, /* value= */ mTimeZone != null);
logParam(callerPackage, LOCALE_PROVIDED_PARAM, /* value= */ mLocale != null);
+ logParam(callerPackage, DEMO_DEVICE, mDemoDevice);
}
private void logParam(String callerPackage, String param, boolean value) {
@@ -204,6 +221,9 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
// Default to allowing control over sensor permission grants.
boolean mDeviceOwnerCanGrantSensorsPermissions = true;
@NonNull private PersistableBundle mAdminExtras;
+ // Default is normal user devices
+ boolean mDemoDevice = false;
+
/**
* Initialize a new {@link Builder} to construct a
@@ -289,6 +309,16 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
}
/**
+ * Marks the device as a demo device, see {@link Settings.Global#DEVICE_DEMO_MODE}. The
+ * default value if unset is {@code false}.
+ */
+ @NonNull
+ public Builder setDemoDevice(boolean demoDevice) {
+ this.mDemoDevice = demoDevice;
+ return this;
+ }
+
+ /**
* Combines all of the attributes that have been set on this {@code Builder}
*
* @return a new {@link FullyManagedDeviceProvisioningParams} object.
@@ -303,7 +333,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
mLocalTime,
mLocale,
mDeviceOwnerCanGrantSensorsPermissions,
- mAdminExtras);
+ mAdminExtras,
+ mDemoDevice);
}
}
@@ -327,6 +358,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
+ ", mDeviceOwnerCanGrantSensorsPermissions="
+ mDeviceOwnerCanGrantSensorsPermissions
+ ", mAdminExtras=" + mAdminExtras
+ + ", mDemoDevice=" + mDemoDevice
+ '}';
}
@@ -340,6 +372,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
dest.writeString(mLocale == null ? null : mLocale.toLanguageTag());
dest.writeBoolean(mDeviceOwnerCanGrantSensorsPermissions);
dest.writePersistableBundle(mAdminExtras);
+ dest.writeBoolean(mDemoDevice);
}
@NonNull
@@ -355,6 +388,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
String locale = in.readString();
boolean deviceOwnerCanGrantSensorsPermissions = in.readBoolean();
PersistableBundle adminExtras = in.readPersistableBundle();
+ boolean demoDevice = in.readBoolean();
return new FullyManagedDeviceProvisioningParams(
componentName,
@@ -364,7 +398,8 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
localtime,
locale,
deviceOwnerCanGrantSensorsPermissions,
- adminExtras);
+ adminExtras,
+ demoDevice);
}
@Override
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
index 6a6d76d20259..469a9bfe59ef 100644
--- a/core/java/android/app/servertransaction/ActivityTransactionItem.java
+++ b/core/java/android/app/servertransaction/ActivityTransactionItem.java
@@ -64,11 +64,11 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem {
final ActivityClientRecord r = client.getActivityClient(token);
if (r == null) {
throw new IllegalArgumentException("Activity client record must not be null to execute "
- + "transaction item");
+ + "transaction item: " + this);
}
if (client.getActivity(token) == null) {
throw new IllegalArgumentException("Activity must not be null to execute "
- + "transaction item");
+ + "transaction item: " + this);
}
return r;
}
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index abf1058f45a2..d7e09519bfb7 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -179,7 +179,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readPersistableBundle(getClass().getClassLoader()),
in.createTypedArrayList(ResultInfo.CREATOR),
in.createTypedArrayList(ReferrerIntent.CREATOR),
- readActivityOptions(in), in.readBoolean(),
+ ActivityOptions.fromBundle(in.readBundle()), in.readBoolean(),
in.readTypedObject(ProfilerInfo.CREATOR),
in.readStrongBinder(),
IActivityClientController.Stub.asInterface(in.readStrongBinder()),
@@ -187,11 +187,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readBoolean());
}
- private static ActivityOptions readActivityOptions(Parcel in) {
- Bundle bundle = in.readBundle();
- return bundle != null ? ActivityOptions.fromBundle(bundle) : null;
- }
-
public static final @NonNull Creator<LaunchActivityItem> CREATOR =
new Creator<LaunchActivityItem>() {
public LaunchActivityItem createFromParcel(Parcel in) {
diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java
index f267060d1be6..15f65f6d9d26 100644
--- a/core/java/android/app/servertransaction/StartActivityItem.java
+++ b/core/java/android/app/servertransaction/StartActivityItem.java
@@ -23,7 +23,6 @@ import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
-import android.os.Bundle;
import android.os.Parcel;
import android.os.Trace;
@@ -84,8 +83,7 @@ public class StartActivityItem extends ActivityLifecycleItem {
/** Read from Parcel. */
private StartActivityItem(Parcel in) {
- Bundle bundle = in.readBundle();
- mActivityOptions = bundle != null ? ActivityOptions.fromBundle(bundle) : null;
+ mActivityOptions = ActivityOptions.fromBundle(in.readBundle());
}
public static final @NonNull Creator<StartActivityItem> CREATOR =
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 60efb4d3ec81..2bda020192d5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2011,9 +2011,9 @@ public abstract class Context {
* @hide
*/
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
- @SystemApi
- public void startActivityAsUser(@RequiresPermission @NonNull Intent intent,
- @Nullable Bundle options, @NonNull UserHandle userId) {
+ @UnsupportedAppUsage
+ public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
+ UserHandle userId) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 673127e9f808..2961b5505794 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2084,7 +2084,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
splitNames = source.createString8Array();
splitSourceDirs = source.createString8Array();
splitPublicSourceDirs = source.createString8Array();
- splitDependencies = source.readSparseArray(null);
+ splitDependencies = source.readSparseArray(null, int[].class);
nativeLibraryDir = source.readString8();
secondaryNativeLibraryDir = source.readString8();
nativeLibraryRootDir = source.readString8();
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 18e205f2e79e..8d6c8e8d9f62 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -57,4 +57,5 @@ interface IPackageInstallerSession {
int getParentSessionId();
boolean isStaged();
+ int getInstallFlags();
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e9e6cd3a54c5..0f236dfe1a8b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -497,21 +497,10 @@ interface IPackageManager {
void enterSafeMode();
@UnsupportedAppUsage
boolean isSafeMode();
- void systemReady();
@UnsupportedAppUsage
boolean hasSystemUidErrors();
/**
- * Ask the package manager to fstrim the disk if needed.
- */
- void performFstrimIfNeeded();
-
- /**
- * Ask the package manager to update packages if needed.
- */
- void updatePackagesIfNeeded();
-
- /**
* Notify the package manager that a package is going to be used and why.
*
* See PackageManager.NOTIFY_PACKAGE_USE_* for reasons.
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 67a2dc84728d..3bdef50c26f5 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1586,6 +1586,18 @@ public class PackageInstaller {
}
/**
+ * @return Session's {@link SessionParams#installFlags}.
+ * @hide
+ */
+ public int getInstallFlags() {
+ try {
+ return mSession.getInstallFlags();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* @return the session ID of the multi-package session that this belongs to or
* {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session.
*/
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index abdc64c56ead..d8ebb628452a 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -298,4 +298,33 @@ public interface BiometricFingerprintConstants {
* @hide
*/
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+
+ /**
+ * Whether the FingerprintAcquired message is a signal to turn off HBM
+ */
+ static boolean shouldTurnOffHbm(@FingerprintAcquired int acquiredInfo) {
+ switch (acquiredInfo) {
+ case FINGERPRINT_ACQUIRED_START:
+ // Authentication just began
+ return false;
+ case FINGERPRINT_ACQUIRED_GOOD:
+ // Good image captured. Turn off HBM. Success/Reject comes after, which is when
+ // hideUdfpsOverlay will be called.
+ return true;
+ case FINGERPRINT_ACQUIRED_PARTIAL:
+ case FINGERPRINT_ACQUIRED_INSUFFICIENT:
+ case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
+ case FINGERPRINT_ACQUIRED_TOO_SLOW:
+ case FINGERPRINT_ACQUIRED_TOO_FAST:
+ case FINGERPRINT_ACQUIRED_IMMOBILE:
+ case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+ case FINGERPRINT_ACQUIRED_VENDOR:
+ // Bad image captured. Turn off HBM. Matcher will not run, so there's no need to
+ // keep HBM on.
+ return true;
+ case FINGERPRINT_ACQUIRED_UNKNOWN:
+ default:
+ return false;
+ }
+ }
}
diff --git a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
index cbd84e77e72a..14ed689af26f 100644
--- a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
+++ b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
@@ -230,6 +230,7 @@ public final class DynamicRangeProfiles {
}
mProfileMap.put(STANDARD, standardConstraints);
+ mLookahedLatencyMap.put(STANDARD, false);
}
diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
index 648edda62171..3cca1b38e5e2 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
@@ -28,9 +28,10 @@ oneway interface IUdfpsOverlayController {
// Hides the overlay.
void hideUdfpsOverlay(int sensorId);
- // Good image captured. Turn off HBM. Success/Reject comes after, which is when hideUdfpsOverlay
- // will be called.
- void onAcquiredGood(int sensorId);
+ // Check acquiredInfo for the acquired type (BiometricFingerprintConstants#FingerprintAcquired).
+ // Check BiometricFingerprintConstants#shouldTurnOffHbm for whether the acquiredInfo
+ // should turn off HBM.
+ void onAcquired(int sensorId, int acquiredInfo);
// Notifies of enrollment progress changes.
void onEnrollmentProgress(int sensorId, int remaining);
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index af57f793bf73..02302a20fe38 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -40,6 +40,7 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.inputmethod.CancellationGroup;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
@@ -70,7 +71,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
private static final int DO_SET_INPUT_CONTEXT = 20;
private static final int DO_UNSET_INPUT_CONTEXT = 30;
private static final int DO_START_INPUT = 32;
- private static final int DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED = 35;
+ private static final int DO_ON_NAV_BUTTON_FLAGS_CHANGED = 35;
private static final int DO_CREATE_SESSION = 40;
private static final int DO_SET_SESSION_ENABLED = 45;
private static final int DO_SHOW_SOFT_INPUT = 60;
@@ -176,7 +177,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
try {
inputMethod.initializeInternal((IBinder) args.arg1,
(IInputMethodPrivilegedOperations) args.arg2, msg.arg1,
- (boolean) args.arg3, msg.arg2 != 0);
+ (boolean) args.arg3, msg.arg2);
} finally {
args.recycle();
}
@@ -196,22 +197,20 @@ class IInputMethodWrapper extends IInputMethod.Stub
final EditorInfo info = (EditorInfo) args.arg3;
final CancellationGroup cancellationGroup = (CancellationGroup) args.arg4;
final boolean restarting = args.argi5 == 1;
- final boolean shouldShowImeSwitcherWhenImeIsShown = args.argi6 != 0;
+ @InputMethodNavButtonFlags
+ final int navButtonFlags = args.argi6;
final InputConnection ic = inputContext != null
? new RemoteInputConnection(mTarget, inputContext, cancellationGroup)
: null;
info.makeCompatible(mTargetSdkVersion);
inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken,
- shouldShowImeSwitcherWhenImeIsShown);
+ navButtonFlags);
args.recycle();
return;
}
- case DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED: {
- final boolean shouldShowImeSwitcherWhenImeIsShown = msg.arg1 != 0;
- inputMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
- shouldShowImeSwitcherWhenImeIsShown);
+ case DO_ON_NAV_BUTTON_FLAGS_CHANGED:
+ inputMethod.onNavButtonFlagsChanged(msg.arg1);
return;
- }
case DO_CREATE_SESSION: {
SomeArgs args = (SomeArgs)msg.obj;
inputMethod.createSession(new InputMethodSessionCallbackWrapper(
@@ -301,10 +300,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
@Override
public void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
int configChanges, boolean stylusHwSupported,
- boolean shouldShowImeSwitcherWhenImeIsShown) {
+ @InputMethodNavButtonFlags int navButtonFlags) {
mCaller.executeOrSendMessage(mCaller.obtainMessageIIOOO(DO_INITIALIZE_INTERNAL,
- configChanges, shouldShowImeSwitcherWhenImeIsShown ? 1 : 0, token, privOps,
- stylusHwSupported));
+ configChanges, navButtonFlags, token, privOps, stylusHwSupported));
}
@BinderThread
@@ -344,23 +342,21 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread
@Override
public void startInput(IBinder startInputToken, IInputContext inputContext,
- EditorInfo attribute, boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ EditorInfo attribute, boolean restarting,
+ @InputMethodNavButtonFlags int navButtonFlags) {
if (mCancellationGroup == null) {
Log.e(TAG, "startInput must be called after bindInput.");
mCancellationGroup = new CancellationGroup();
}
mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOII(DO_START_INPUT, startInputToken,
- inputContext, attribute, mCancellationGroup, restarting ? 1 : 0,
- shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
+ inputContext, attribute, mCancellationGroup, restarting ? 1 : 0, navButtonFlags));
}
@BinderThread
@Override
- public void onShouldShowImeSwitcherWhenImeIsShownChanged(
- boolean shouldShowImeSwitcherWhenImeIsShown) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageI(
- DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED,
- shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
+ public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+ mCaller.executeOrSendMessage(
+ mCaller.obtainMessageI(DO_ON_NAV_BUTTON_FLAGS_CHANGED, navButtonFlags));
}
@BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index fbc0732affe1..60cd4181e933 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -140,6 +140,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.ImeTracing;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
@@ -660,7 +661,7 @@ public class InputMethodService extends AbstractInputMethodService {
@Override
public final void initializeInternal(@NonNull IBinder token,
IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
- boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags) {
if (mDestroyed) {
Log.i(TAG, "The InputMethodService has already onDestroyed()."
+ "Ignore the initialization.");
@@ -673,8 +674,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (stylusHwSupported) {
mInkWindow = new InkWindow(mWindow.getContext());
}
- mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
- shouldShowImeSwitcherWhenImeIsShown);
+ mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
attachToken(token);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -784,10 +784,9 @@ public class InputMethodService extends AbstractInputMethodService {
@Override
public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
- @NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
mPrivOps.reportStartInputAsync(startInputToken);
- mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
- shouldShowImeSwitcherWhenImeIsShown);
+ mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
if (restarting) {
restartInput(inputConnection, editorInfo);
} else {
@@ -801,10 +800,8 @@ public class InputMethodService extends AbstractInputMethodService {
*/
@MainThread
@Override
- public void onShouldShowImeSwitcherWhenImeIsShownChanged(
- boolean shouldShowImeSwitcherWhenImeIsShown) {
- mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
- shouldShowImeSwitcherWhenImeIsShown);
+ public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+ mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
}
/**
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index 19fa01de4a5f..0f9075b498ae 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -16,7 +16,6 @@
package android.inputmethodservice;
-import static android.content.Intent.ACTION_OVERLAY_CHANGED;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import android.animation.ValueAnimator;
@@ -24,18 +23,12 @@ import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.StatusBarManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
import android.inputmethodservice.navigationbar.NavigationBarFrame;
import android.inputmethodservice.navigationbar.NavigationBarView;
-import android.os.PatternMatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -49,6 +42,8 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
+
import java.util.Objects;
/**
@@ -77,8 +72,7 @@ final class NavigationBarController {
default void onDestroy() {
}
- default void setShouldShowImeSwitcherWhenImeIsShown(
- boolean shouldShowImeSwitcherWhenImeIsShown) {
+ default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
}
default String toDebugString() {
@@ -117,8 +111,8 @@ final class NavigationBarController {
mImpl.onDestroy();
}
- void setShouldShowImeSwitcherWhenImeIsShown(boolean shouldShowImeSwitcherWhenImeIsShown) {
- mImpl.setShouldShowImeSwitcherWhenImeIsShown(shouldShowImeSwitcherWhenImeIsShown);
+ void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+ mImpl.onNavButtonFlagsChanged(navButtonFlags);
}
String toDebugString() {
@@ -144,9 +138,6 @@ final class NavigationBarController {
@Nullable
Insets mLastInsets;
- @Nullable
- private BroadcastReceiver mSystemOverlayChangedReceiver;
-
private boolean mShouldShowImeSwitcherWhenImeIsShown;
@Appearance
@@ -359,14 +350,6 @@ final class NavigationBarController {
});
}
- private boolean imeDrawsImeNavBar() {
- final Resources resources = mService.getResources();
- if (resources == null) {
- return false;
- }
- return resources.getBoolean(com.android.internal.R.bool.config_imeDrawsImeNavBar);
- }
-
@Override
public void onSoftInputWindowCreated(@NonNull SoftInputWindow softInputWindow) {
final Window window = softInputWindow.getWindow();
@@ -379,27 +362,6 @@ final class NavigationBarController {
if (mDestroyed) {
return;
}
- mImeDrawsImeNavBar = imeDrawsImeNavBar();
- if (mSystemOverlayChangedReceiver == null) {
- final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
- intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
- intentFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL);
- mSystemOverlayChangedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mDestroyed) {
- return;
- }
- mImeDrawsImeNavBar = imeDrawsImeNavBar();
- if (mImeDrawsImeNavBar) {
- installNavigationBarFrameIfNecessary();
- } else {
- uninstallNavigationBarFrameIfNecessary();
- }
- }
- };
- mService.registerReceiver(mSystemOverlayChangedReceiver, intentFilter);
- }
installNavigationBarFrameIfNecessary();
}
@@ -412,10 +374,6 @@ final class NavigationBarController {
mTintAnimator.cancel();
mTintAnimator = null;
}
- if (mSystemOverlayChangedReceiver != null) {
- mService.unregisterReceiver(mSystemOverlayChangedReceiver);
- mSystemOverlayChangedReceiver = null;
- }
mDestroyed = true;
}
@@ -448,28 +406,43 @@ final class NavigationBarController {
}
@Override
- public void setShouldShowImeSwitcherWhenImeIsShown(
- boolean shouldShowImeSwitcherWhenImeIsShown) {
+ public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
if (mDestroyed) {
return;
}
- if (mShouldShowImeSwitcherWhenImeIsShown == shouldShowImeSwitcherWhenImeIsShown) {
- return;
- }
+
+ final boolean imeDrawsImeNavBar =
+ (navButtonFlags & InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR) != 0;
+ final boolean shouldShowImeSwitcherWhenImeIsShown =
+ (navButtonFlags & InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN)
+ != 0;
+
+ mImeDrawsImeNavBar = imeDrawsImeNavBar;
+ final boolean prevShouldShowImeSwitcherWhenImeIsShown =
+ mShouldShowImeSwitcherWhenImeIsShown;
mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown;
- if (mNavigationBarFrame == null) {
- return;
- }
- final NavigationBarView navigationBarView =
- mNavigationBarFrame.findViewByPredicate(NavigationBarView.class::isInstance);
- if (navigationBarView == null) {
- return;
+ if (imeDrawsImeNavBar) {
+ installNavigationBarFrameIfNecessary();
+ if (mNavigationBarFrame == null) {
+ return;
+ }
+ if (mShouldShowImeSwitcherWhenImeIsShown
+ == prevShouldShowImeSwitcherWhenImeIsShown) {
+ return;
+ }
+ final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
+ NavigationBarView.class::isInstance);
+ if (navigationBarView == null) {
+ return;
+ }
+ final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
+ | (shouldShowImeSwitcherWhenImeIsShown
+ ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
+ navigationBarView.setNavigationIconHints(hints);
+ } else {
+ uninstallNavigationBarFrameIfNecessary();
}
- final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
- | (shouldShowImeSwitcherWhenImeIsShown
- ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
- navigationBarView.setNavigationIconHints(hints);
}
@Override
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 0ce9c70569b5..731d1ba78299 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -142,9 +142,13 @@ public final class Tag implements Parcelable {
mTagService = tagService;
mConnectedTechnology = -1;
+ mCookie = SystemClock.elapsedRealtime();
+
+ if (tagService == null) {
+ return;
+ }
try {
- mCookie = SystemClock.elapsedRealtime();
tagService.setTagUpToDate(mCookie);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
@@ -370,6 +374,10 @@ public final class Tag implements Parcelable {
/** @hide */
@UnsupportedAppUsage
public INfcTag getTagService() {
+ if (mTagService == null) {
+ return null;
+ }
+
try {
if (!mTagService.isTagUpToDate(mCookie)) {
String id_str = "";
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index 4e0995fb8792..db5bc7024e0b 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -47,7 +47,13 @@ public class ExternalVibration implements Parcelable {
this(uid, pkg, attrs, controller, new Binder());
}
- private ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
+ /**
+ * Full constructor, but exposed to construct the ExternalVibration with an explicit binder
+ * token (for mocks).
+ *
+ * @hide
+ */
+ public ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
@NonNull IExternalVibrationController controller, @NonNull IBinder token) {
mUid = uid;
mPkg = Preconditions.checkNotNull(pkg);
@@ -166,7 +172,7 @@ public class ExternalVibration implements Parcelable {
+ "pkg=" + mPkg + ", "
+ "attrs=" + mAttrs + ", "
+ "controller=" + mController
- + "token=" + mController
+ + "token=" + mToken
+ "}";
}
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
new file mode 100644
index 000000000000..00734c806b7e
--- /dev/null
+++ b/core/java/android/os/IpcDataCache.java
@@ -0,0 +1,364 @@
+/*
+ * 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.os;
+
+import android.app.PropertyInvalidatedCache;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FastPrintWriter;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * LRU cache that's invalidated when an opaque value in a property changes. Self-synchronizing,
+ * but doesn't hold a lock across data fetches on query misses.
+ *
+ * The intended use case is caching frequently-read, seldom-changed information normally retrieved
+ * across interprocess communication. Imagine that you've written a user birthday information
+ * daemon called "birthdayd" that exposes an {@code IUserBirthdayService} interface over
+ * binder. That binder interface looks something like this:
+ *
+ * <pre>
+ * parcelable Birthday {
+ * int month;
+ * int day;
+ * }
+ * interface IUserBirthdayService {
+ * Birthday getUserBirthday(int userId);
+ * }
+ * </pre>
+ *
+ * Suppose the service implementation itself looks like this...
+ *
+ * <pre>
+ * public class UserBirthdayServiceImpl implements IUserBirthdayService {
+ * private final HashMap&lt;Integer, Birthday%&gt; mUidToBirthday;
+ * {@literal @}Override
+ * public synchronized Birthday getUserBirthday(int userId) {
+ * return mUidToBirthday.get(userId);
+ * }
+ * private synchronized void updateBirthdays(Map&lt;Integer, Birthday%&gt; uidToBirthday) {
+ * mUidToBirthday.clear();
+ * mUidToBirthday.putAll(uidToBirthday);
+ * }
+ * }
+ * </pre>
+ *
+ * ... and we have a client in frameworks (loaded into every app process) that looks like this:
+ *
+ * <pre>
+ * public class ActivityThread {
+ * ...
+ * public Birthday getUserBirthday(int userId) {
+ * return GetService("birthdayd").getUserBirthday(userId);
+ * }
+ * ...
+ * }
+ * </pre>
+ *
+ * With this code, every time an app calls {@code getUserBirthday(uid)}, we make a binder call to
+ * the birthdayd process and consult its database of birthdays. If we query user birthdays
+ * frequently, we do a lot of work that we don't have to do, since user birthdays change
+ * infrequently.
+ *
+ * IpcDataCache is part of a pattern for optimizing this kind of information-querying code. Using
+ * {@code IpcDataCache}, you'd write the client this way:
+ *
+ * <pre>
+ * public class ActivityThread {
+ * ...
+ * private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ * new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ * {@literal @}Override
+ * public Birthday apply(Integer) {
+ * return GetService("birthdayd").getUserBirthday(userId);
+ * }
+ * };
+ * private static final int BDAY_CACHE_MAX = 8; // Maximum birthdays to cache
+ * private static final String BDAY_API = "getUserBirthday";
+ * private final IpcDataCache&lt;Integer, Birthday%&gt; mBirthdayCache = new
+ * IpcDataCache&lt;Integer, Birthday%&gt;(
+ * BDAY_CACHE_MAX, MODULE_SYSTEM, BDAY_API, BDAY_API, mBirthdayQuery);
+ *
+ * public void disableUserBirthdayCache() {
+ * mBirthdayCache.disableForCurrentProcess();
+ * }
+ * public void invalidateUserBirthdayCache() {
+ * mBirthdayCache.invalidateCache();
+ * }
+ * public Birthday getUserBirthday(int userId) {
+ * return mBirthdayCache.query(userId);
+ * }
+ * ...
+ * }
+ * </pre>
+ *
+ * With this cache, clients perform a binder call to birthdayd if asking for a user's birthday
+ * for the first time; on subsequent queries, we return the already-known Birthday object.
+ *
+ * The second parameter to the IpcDataCache constructor is a string that identifies the "module"
+ * that owns the cache. There are some well-known modules (such as {@code MODULE_SYSTEM} but any
+ * string is permitted. The third parameters is the name of the API being cached; this, too, can
+ * any value. The fourth is the name of the cache. The cache is usually named after th API.
+ * Some things you must know about the three strings:
+ * <list>
+ * <ul> The system property that controls the cache is named {@code cache_key.<module>.<api>}.
+ * Usually, the SELinux rules permit a process to write a system property (and therefore
+ * invalidate a cache) based on the wildcard {@code cache_key.<module>.*}. This means that
+ * although the cache can be constructed with any module string, whatever string is chosen must be
+ * consistent with the SELinux configuration.
+ * <ul> The API name can be any string of alphanumeric characters. All caches with the same API
+ * are invalidated at the same time. If a server supports several caches and all are invalidated
+ * in common, then it is most efficient to assign the same API string to every cache.
+ * <ul> The cache name can be any string. In debug output, the name is used to distiguish between
+ * caches with the same API name. The cache name is also used when disabling caches in the
+ * current process. So, invalidation is based on the module+api but disabling (which is generally
+ * a once-per-process operation) is based on the cache name.
+ * </list>
+ *
+ * User birthdays do occasionally change, so we have to modify the server to invalidate this
+ * cache when necessary. That invalidation code looks like this:
+ *
+ * <pre>
+ * public class UserBirthdayServiceImpl {
+ * ...
+ * public UserBirthdayServiceImpl() {
+ * ...
+ * ActivityThread.currentActivityThread().disableUserBirthdayCache();
+ * ActivityThread.currentActivityThread().invalidateUserBirthdayCache();
+ * }
+ *
+ * private synchronized void updateBirthdays(Map&lt;Integer, Birthday%&gt; uidToBirthday) {
+ * mUidToBirthday.clear();
+ * mUidToBirthday.putAll(uidToBirthday);
+ * ActivityThread.currentActivityThread().invalidateUserBirthdayCache();
+ * }
+ * ...
+ * }
+ * </pre>
+ *
+ * The call to {@code IpcDataCache.invalidateCache()} guarantees that all clients will re-fetch
+ * birthdays from binder during consequent calls to
+ * {@code ActivityThread.getUserBirthday()}. Because the invalidate call happens with the lock
+ * held, we maintain consistency between different client views of the birthday state. The use of
+ * IpcDataCache in this idiomatic way introduces no new race conditions.
+ *
+ * IpcDataCache has a few other features for doing things like incremental enhancement of cached
+ * values and invalidation of multiple caches (that all share the same property key) at once.
+ *
+ * {@code BDAY_CACHE_KEY} is the name of a property that we set to an opaque unique value each
+ * time we update the cache. SELinux configuration must allow everyone to read this property
+ * and it must allow any process that needs to invalidate the cache (here, birthdayd) to write
+ * the property. (These properties conventionally begin with the "cache_key." prefix.)
+ *
+ * The {@code UserBirthdayServiceImpl} constructor calls {@code disableUserBirthdayCache()} so
+ * that calls to {@code getUserBirthday} from inside birthdayd don't go through the cache. In this
+ * local case, there's no IPC, so use of the cache is (depending on exact circumstance)
+ * unnecessary.
+ *
+ * There may be queries for which it is more efficient to bypass the cache than to cache the
+ * result. This would be true, for example, if some queries would require frequent cache
+ * invalidation while other queries require infrequent invalidation. To expand on the birthday
+ * example, suppose that there is a userId that signifies "the next birthday". When passed this
+ * userId, the server returns the next birthday among all users - this value changes as time
+ * advances. The userId value can be cached, but the cache must be invalidated whenever a
+ * birthday occurs, and this invalidates all birthdays. If there is a large number of users,
+ * invalidation will happen so often that the cache provides no value.
+ *
+ * The class provides a bypass mechanism to handle this situation.
+ * <pre>
+ * public class ActivityThread {
+ * ...
+ * private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ * new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ * {@literal @}Override
+ * public Birthday apply(Integer) {
+ * return GetService("birthdayd").getUserBirthday(userId);
+ * }
+ * {@literal @}Override
+ * public boolean shouldBypassQuery(Integer userId) {
+ * return userId == NEXT_BIRTHDAY;
+ * }
+ * };
+ * ...
+ * }
+ * </pre>
+ *
+ * If the {@code shouldBypassQuery()} method returns true then the cache is not used for that
+ * particular query. The {@code shouldBypassQuery()} method is not abstract and the default
+ * implementation returns false.
+ *
+ * For security, there is a allowlist of processes that are allowed to invalidate a cache. The
+ * allowlist includes normal runtime processes but does not include test processes. Test
+ * processes must call {@code IpcDataCache.disableForTestMode()} to disable all cache activity in
+ * that process.
+ *
+ * Caching can be disabled completely by initializing {@code sEnabled} to false and rebuilding.
+ *
+ * To test a binder cache, create one or more tests that exercise the binder method. This should
+ * be done twice: once with production code and once with a special image that sets {@code DEBUG}
+ * and {@code VERIFY} true. In the latter case, verify that no cache inconsistencies are
+ * reported. If a cache inconsistency is reported, however, it might be a false positive. This
+ * happens if the server side data can be read and written non-atomically with respect to cache
+ * invalidation.
+ *
+ * @param <Query> The class used to index cache entries: must be hashable and comparable
+ * @param <Result> The class holding cache entries; use a boxed primitive if possible
+ * @hide
+ */
+@TestApi
+@SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, Result> {
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public static abstract class QueryHandler<Q,R>
+ extends PropertyInvalidatedCache.QueryHandler<Q,R> {
+ /**
+ * Compute a result given a query. The semantics are those of Functor.
+ */
+ public abstract @Nullable R apply(@NonNull Q query);
+
+ /**
+ * Return true if a query should not use the cache. The default implementation
+ * always uses the cache.
+ */
+ public boolean shouldBypassCache(@NonNull Q query) {
+ return false;
+ }
+ };
+
+ /**
+ * The module used for unit tests and cts tests. It is expected that no process in
+ * the system has permissions to write properties with this module.
+ * @hide
+ */
+ @TestApi
+ public static final String MODULE_TEST = PropertyInvalidatedCache.MODULE_TEST;
+
+ /**
+ * The module used for system server/framework caches. This is not visible outside
+ * the system processes.
+ * @hide
+ */
+ @TestApi
+ public static final String MODULE_SYSTEM = PropertyInvalidatedCache.MODULE_SYSTEM;
+
+ /**
+ * The module used for bluetooth caches.
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public static final String MODULE_BLUETOOTH = PropertyInvalidatedCache.MODULE_BLUETOOTH;
+
+ /**
+ * Make a new property invalidated cache. The key is computed from the module and api
+ * parameters.
+ *
+ * @param maxEntries Maximum number of entries to cache; LRU discard
+ * @param module The module under which the cache key should be placed.
+ * @param api The api this cache front-ends. The api must be a Java identifier but
+ * need not be an actual api.
+ * @param cacheName Name of this cache in debug and dumpsys
+ * @param computer The code to compute values that are not in the cache.
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public IpcDataCache(int maxEntries, @NonNull String module, @NonNull String api,
+ @NonNull String cacheName, @NonNull QueryHandler<Query, Result> computer) {
+ super(maxEntries, module, api, cacheName, computer);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ @Override
+ public void disableForCurrentProcess() {
+ super.disableForCurrentProcess();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public static void disableForCurrentProcess(@NonNull String cacheName) {
+ PropertyInvalidatedCache.disableForCurrentProcess(cacheName);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ @Override
+ public @Nullable Result query(@NonNull Query query) {
+ return super.query(query);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ @Override
+ public void invalidateCache() {
+ super.invalidateCache();
+ }
+
+ /**
+ * Invalidate caches in all processes that are keyed for the module and api.
+ * @hide
+ */
+ @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public static void invalidateCache(@NonNull String module, @NonNull String api) {
+ PropertyInvalidatedCache.invalidateCache(module, api);
+ }
+}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index f069158c9242..8cb03443528c 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -374,7 +374,7 @@ public class Process {
* ** Keep in sync with utils/threads.h **
* ***************************************
*/
-
+
/**
* Lowest available thread priority. Only for those who really, really
* don't want to run if anything else is happening.
@@ -383,7 +383,7 @@ public class Process {
* {@link java.lang.Thread} class.
*/
public static final int THREAD_PRIORITY_LOWEST = 19;
-
+
/**
* Standard priority background threads. This gives your thread a slightly
* lower than normal priority, so that it will have less chance of impacting
@@ -393,7 +393,7 @@ public class Process {
* {@link java.lang.Thread} class.
*/
public static final int THREAD_PRIORITY_BACKGROUND = 10;
-
+
/**
* Standard priority of threads that are currently running a user interface
* that the user is interacting with. Applications can not normally
@@ -404,7 +404,7 @@ public class Process {
* {@link java.lang.Thread} class.
*/
public static final int THREAD_PRIORITY_FOREGROUND = -2;
-
+
/**
* Standard priority of system display threads, involved in updating
* the user interface. Applications can not
@@ -414,7 +414,7 @@ public class Process {
* {@link java.lang.Thread} class.
*/
public static final int THREAD_PRIORITY_DISPLAY = -4;
-
+
/**
* Standard priority of the most important display threads, for compositing
* the screen and retrieving input events. Applications can not normally
@@ -654,19 +654,19 @@ public class Process {
/**
* Start a new process.
- *
+ *
* <p>If processes are enabled, a new process is created and the
* static main() function of a <var>processClass</var> is executed there.
* The process will continue running after this function returns.
- *
+ *
* <p>If processes are not enabled, a new thread in the caller's
* process is created and main() of <var>processClass</var> called there.
- *
+ *
* <p>The niceName parameter, if not an empty string, is a custom name to
* give to the process instead of using processClass. This allows you to
* make easily identifyable processes even if you are using the same base
* <var>processClass</var> to start them.
- *
+ *
* When invokeWith is not null, the process will be started as a fresh app
* and not a zygote fork. Note that this is only allowed for uid 0 or when
* runtimeFlags contains DEBUG_ENABLE_DEBUGGER.
@@ -906,6 +906,7 @@ public class Process {
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
+ @TestApi
public static final boolean isSdkSandboxUid(int uid) {
uid = UserHandle.getAppId(uid);
return (uid >= FIRST_SDK_SANDBOX_UID && uid <= LAST_SDK_SANDBOX_UID);
@@ -913,12 +914,13 @@ public class Process {
/**
*
- * Returns the app process corresponding to a sdk sandbox process.
+ * Returns the app process corresponding to an sdk sandbox process.
*
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
- public static final int toAppUid(int uid) {
+ @TestApi
+ public static final int getAppUidForSdkSandboxUid(int uid) {
return uid - (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID);
}
@@ -947,7 +949,7 @@ public class Process {
* directly to a uid.
*/
public static final native int getUidForName(String name);
-
+
/**
* Returns the GID assigned to a particular user name, or -1 if there is
* none. If the given string consists of only numbers, it is converted
@@ -1002,11 +1004,11 @@ public class Process {
/**
* Set the priority of a thread, based on Linux priorities.
- *
+ *
* @param tid The identifier of the thread/process to change.
* @param priority A Linux priority level, from -20 for highest scheduling
* priority to 19 for lowest scheduling priority.
- *
+ *
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
@@ -1065,7 +1067,7 @@ public class Process {
* @hide
* @param pid The identifier of the process to change.
* @param group The target group for this process from THREAD_GROUP_*.
- *
+ *
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
@@ -1154,37 +1156,37 @@ public class Process {
/**
* Set the priority of the calling thread, based on Linux priorities. See
* {@link #setThreadPriority(int, int)} for more information.
- *
+ *
* @param priority A Linux priority level, from -20 for highest scheduling
* priority to 19 for lowest scheduling priority.
- *
+ *
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
* not have permission to modify the given thread, or to use the given
* priority.
- *
+ *
* @see #setThreadPriority(int, int)
*/
public static final native void setThreadPriority(int priority)
throws IllegalArgumentException, SecurityException;
-
+
/**
* Return the current priority of a thread, based on Linux priorities.
- *
+ *
* @param tid The identifier of the thread/process. If tid equals zero, the priority of the
* calling process/thread will be returned.
- *
+ *
* @return Returns the current priority, as a Linux priority level,
* from -20 for highest scheduling priority to 19 for lowest scheduling
* priority.
- *
+ *
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
*/
public static final native int getThreadPriority(int tid)
throws IllegalArgumentException;
-
+
/**
* Return the current scheduling policy of a thread, based on Linux.
*
@@ -1198,7 +1200,7 @@ public class Process {
*
* {@hide}
*/
-
+
@TestApi
public static final native int getThreadScheduler(int tid)
throws IllegalArgumentException;
@@ -1224,7 +1226,7 @@ public class Process {
/**
* Determine whether the current environment supports multiple processes.
- *
+ *
* @return Returns true if the system can run in multiple processes, else
* false if everything is running in a single process.
*
@@ -1251,9 +1253,9 @@ public class Process {
/**
* Change this process's argv[0] parameter. This can be useful to show
* more descriptive information in things like the 'ps' command.
- *
+ *
* @param text The new name of this process.
- *
+ *
* {@hide}
*/
@UnsupportedAppUsage(maxTargetSdk = VERSION_CODES.S, publicAlternatives = "Do not try to "
@@ -1301,12 +1303,12 @@ public class Process {
/**
* Send a signal to the given process.
- *
+ *
* @param pid The pid of the target process.
* @param signal The signal to send.
*/
public static final native void sendSignal(int pid, int signal);
-
+
/**
* @hide
* Private impl for avoiding a log message... DO NOT USE without doing
@@ -1325,24 +1327,24 @@ public class Process {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public static final native void sendSignalQuiet(int pid, int signal);
-
+
/** @hide */
@UnsupportedAppUsage
public static final native long getFreeMemory();
-
+
/** @hide */
@UnsupportedAppUsage
public static final native long getTotalMemory();
-
+
/** @hide */
@UnsupportedAppUsage
public static final native void readProcLines(String path,
String[] reqFields, long[] outSizes);
-
+
/** @hide */
@UnsupportedAppUsage
public static final native int[] getPids(String path, int[] lastArray);
-
+
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final int PROC_TERM_MASK = 0xff;
@@ -1413,7 +1415,7 @@ public class Process {
/** @hide */
@UnsupportedAppUsage
- public static final native boolean parseProcLine(byte[] buffer, int startIndex,
+ public static final native boolean parseProcLine(byte[] buffer, int startIndex,
int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
/** @hide */
@@ -1422,10 +1424,10 @@ public class Process {
/**
* Gets the total Pss value for a given process, in bytes.
- *
+ *
* @param pid the process to the Pss for
* @return the total Pss value for the given process in bytes,
- * or -1 if the value cannot be determined
+ * or -1 if the value cannot be determined
* @hide
*/
@UnsupportedAppUsage
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index e56f214e30d9..a715c6961359 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2574,6 +2574,9 @@ public class UserManager {
/**
* Checks if the context user is a managed profile.
*
+ * Note that this applies specifically to <em>managed</em> profiles. For profiles in general,
+ * use {@link #isProfile()} instead.
+ *
* @return whether the context user is a managed profile.
*/
@UserHandleAware(
@@ -2593,6 +2596,9 @@ public class UserManager {
* {@link android.Manifest.permission#QUERY_USERS} permission, otherwise the caller
* must be in the same profile group of specified user.
*
+ * Note that this applies specifically to <em>managed</em> profiles. For profiles in general,
+ * use {@link #isProfile()} instead.
+ *
* @return whether the specified user is a managed profile.
* @hide
*/
@@ -3322,7 +3328,7 @@ public class UserManager {
*
* <p>This method can be used by OEMs to "warm" up the user creation by pre-creating some users
* at the first boot, so they when the "real" user is created (for example,
- * by {@link #createUser(String, String, int)} or {@link #createGuest(Context, String)}), it
+ * by {@link #createUser(String, String, int)} or {@link #createGuest(Context)}), it
* takes less time.
*
* <p>This method completes the majority of work necessary for user creation: it
@@ -3359,7 +3365,6 @@ public class UserManager {
/**
* Creates a guest user and configures it.
* @param context an application context
- * @param name the name to set for the user
* @return the {@link UserInfo} object for the created user, or {@code null} if the user
* could not be created.
*
@@ -3367,20 +3372,19 @@ public class UserManager {
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
- public UserInfo createGuest(Context context, String name) {
- UserInfo guest = null;
+ public UserInfo createGuest(Context context) {
try {
- guest = mService.createUserWithThrow(name, USER_TYPE_FULL_GUEST, 0);
+ final UserInfo guest = mService.createUserWithThrow(null, USER_TYPE_FULL_GUEST, 0);
if (guest != null) {
Settings.Secure.putStringForUser(context.getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
}
+ return guest;
} catch (ServiceSpecificException e) {
return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
- return guest;
}
/**
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 722cdbc620a7..7832dccd93a5 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -54,13 +54,13 @@ interface IStorageManager {
*/
void shutdown(IStorageShutdownObserver observer) = 19;
/**
- * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
- * only allows the calling process's UID access to the contents.
- * StorageManagerService will call back to the supplied IObbActionListener to inform
- * it of the terminal state of the call.
+ * Mounts an Opaque Binary Blob (OBB). Only allows the calling process's UID
+ * access to the contents. StorageManagerService will call back to the
+ * supplied IObbActionListener to inform it of the terminal state of the
+ * call.
*/
- void mountObb(in String rawPath, in String canonicalPath, in String key,
- IObbActionListener token, int nonce, in ObbInfo obbInfo) = 21;
+ void mountObb(in String rawPath, in String canonicalPath, IObbActionListener token,
+ int nonce, in ObbInfo obbInfo) = 21;
/**
* Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
* any program using it will be forcibly killed to unmount the image.
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 48e2827f19e1..b501730f1eeb 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -273,12 +273,15 @@ public class StorageManager {
public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
/** {@hide} */
public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
+ /** @hide */
+ public static final int FLAG_STORAGE_SDK = IInstalld.FLAG_STORAGE_SDK;
/** {@hide} */
@IntDef(prefix = "FLAG_STORAGE_", value = {
FLAG_STORAGE_DE,
FLAG_STORAGE_CE,
- FLAG_STORAGE_EXTERNAL
+ FLAG_STORAGE_EXTERNAL,
+ FLAG_STORAGE_SDK,
})
@Retention(RetentionPolicy.SOURCE)
public @interface StorageFlags {}
@@ -677,9 +680,7 @@ public class StorageManager {
}
/**
- * Mount an Opaque Binary Blob (OBB) file. If a <code>key</code> is
- * specified, it is supplied to the mounting process to be used in any
- * encryption used in the OBB.
+ * Mount an Opaque Binary Blob (OBB) file.
* <p>
* The OBB will remain mounted for as long as the StorageManager reference
* is held by the application. As soon as this reference is lost, the OBBs
@@ -692,19 +693,22 @@ public class StorageManager {
* application's OBB that shares its UID.
*
* @param rawPath the path to the OBB file
- * @param key secret used to encrypt the OBB; may be <code>null</code> if no
- * encryption was used on the OBB.
+ * @param key must be <code>null</code>. Previously, some Android device
+ * implementations accepted a non-<code>null</code> key to mount
+ * an encrypted OBB file. However, this never worked reliably and
+ * is no longer supported.
* @param listener will receive the success or failure of the operation
* @return whether the mount call was successfully queued or not
*/
public boolean mountObb(String rawPath, String key, OnObbStateChangeListener listener) {
Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+ Preconditions.checkArgument(key == null, "mounting encrypted OBBs is no longer supported");
Preconditions.checkNotNull(listener, "listener cannot be null");
try {
final String canonicalPath = new File(rawPath).getCanonicalPath();
final int nonce = mObbActionListener.addListener(listener);
- mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce,
+ mStorageManager.mountObb(rawPath, canonicalPath, mObbActionListener, nonce,
getObbInfo(canonicalPath));
return true;
} catch (IOException e) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f2137b30350a..cfef7adb240f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -85,8 +85,10 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.MemoryIntArray;
import android.view.Display;
+import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
+import android.widget.Editor;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -15518,6 +15520,17 @@ public final class Settings {
public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
/**
+ * Toggle for enabling stylus handwriting. When enabled, current Input method receives
+ * stylus {@link MotionEvent}s if an {@link Editor} is focused.
+ *
+ * @hide
+ */
+ @TestApi
+ @Readable
+ @SuppressLint("NoSettingsProvider")
+ public static final String STYLUS_HANDWRITING_ENABLED = "stylus_handwriting_enabled";
+
+ /**
* Exemptions to the hidden API blacklist.
*
* @hide
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 86707598255d..db622d39b785 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -231,7 +231,7 @@ public class DreamService extends Service implements Window.Callback {
* The default value for whether to show complications on the overlay.
* @hide
*/
- public static final boolean DEFAULT_SHOW_COMPLICATIONS = false;
+ public static final boolean DEFAULT_SHOW_COMPLICATIONS = true;
private final IDreamManager mDreamManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS
index f8318054ddfc..489a5f62b49d 100644
--- a/core/java/android/service/dreams/OWNERS
+++ b/core/java/android/service/dreams/OWNERS
@@ -1,3 +1,8 @@
# Bug component: 78010
+brycelee@google.com
dsandler@google.com
+galinap@google.com
+jjaggi@google.com
+michaelwr@google.com
+santoscordon@google.com
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 40beab323576..aebc5e86605a 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -33,6 +33,9 @@ import android.text.TextUtils;
import com.android.internal.annotations.GuardedBy;
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
import java.util.Objects;
import java.util.function.Supplier;
@@ -96,8 +99,8 @@ public class NtpTrustedTime implements TrustedTime {
@Override
public String toString() {
return "TimeResult{"
- + "mTimeMillis=" + mTimeMillis
- + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+ + "mTimeMillis=" + Instant.ofEpochMilli(mTimeMillis)
+ + ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
+ ", mCertaintyMillis=" + mCertaintyMillis
+ '}';
}
@@ -131,6 +134,14 @@ public class NtpTrustedTime implements TrustedTime {
}
};
+ /** An in-memory config override for use during tests. */
+ @Nullable
+ private String mHostnameForTests;
+
+ /** An in-memory config override for use during tests. */
+ @Nullable
+ private Duration mTimeoutForTests;
+
// Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
// forceRefresh().
private volatile TimeResult mTimeResult;
@@ -148,12 +159,23 @@ public class NtpTrustedTime implements TrustedTime {
return sSingleton;
}
+ /**
+ * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+ * test value, i.e. so the normal value will be used next time.
+ */
+ public void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+ synchronized (this) {
+ mHostnameForTests = hostname;
+ mTimeoutForTests = timeout;
+ }
+ }
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean forceRefresh() {
synchronized (this) {
NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
if (connectionInfo == null) {
- // missing server config, so no trusted time available
+ // missing server config, so no NTP time available
if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
return false;
}
@@ -290,6 +312,14 @@ public class NtpTrustedTime implements TrustedTime {
int getTimeoutMillis() {
return mTimeoutMillis;
}
+
+ @Override
+ public String toString() {
+ return "NtpConnectionInfo{"
+ + "mServer='" + mServer + '\''
+ + ", mTimeoutMillis=" + mTimeoutMillis
+ + '}';
+ }
}
@GuardedBy("this")
@@ -297,17 +327,41 @@ public class NtpTrustedTime implements TrustedTime {
final ContentResolver resolver = mContext.getContentResolver();
final Resources res = mContext.getResources();
- final String defaultServer = res.getString(
- com.android.internal.R.string.config_ntpServer);
- final int defaultTimeoutMillis = res.getInteger(
- com.android.internal.R.integer.config_ntpTimeout);
-
- final String secureServer = Settings.Global.getString(
- resolver, Settings.Global.NTP_SERVER);
- final int timeoutMillis = Settings.Global.getInt(
- resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
-
- final String server = secureServer != null ? secureServer : defaultServer;
- return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
+
+ final String hostname;
+ if (mHostnameForTests != null) {
+ hostname = mHostnameForTests;
+ } else {
+ String serverGlobalSetting =
+ Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
+ if (serverGlobalSetting != null) {
+ hostname = serverGlobalSetting;
+ } else {
+ hostname = res.getString(com.android.internal.R.string.config_ntpServer);
+ }
+ }
+
+ final int timeoutMillis;
+ if (mTimeoutForTests != null) {
+ timeoutMillis = (int) mTimeoutForTests.toMillis();
+ } else {
+ int defaultTimeoutMillis =
+ res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
+ timeoutMillis = Settings.Global.getInt(
+ resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+ }
+ return TextUtils.isEmpty(hostname) ? null : new NtpConnectionInfo(hostname, timeoutMillis);
+ }
+
+ /** Prints debug information. */
+ public void dump(PrintWriter pw) {
+ synchronized (this) {
+ pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
+ pw.println("mTimeResult=" + mTimeResult);
+ if (mTimeResult != null) {
+ pw.println("mTimeResult.getAgeMillis()="
+ + Duration.ofMillis(mTimeResult.getAgeMillis()));
+ }
+ }
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3f29e3f3078e..a35a195c50b1 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -201,7 +201,12 @@ interface IWindowManager
boolean isKeyguardSecure(int userId);
void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message);
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)")
void addKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);
+
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)")
void removeKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);
// Requires INTERACT_ACROSS_USERS_FULL permission
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 2b579d09d3a2..ef0c19c8dc02 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -16,20 +16,57 @@
package android.view;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.Region;
import android.gui.TouchOcclusionMode;
import android.os.IBinder;
+import android.os.InputConfig;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
/**
- * Functions as a handle for a window that can receive input.
- * Enables the native input dispatcher to refer indirectly to the window manager's window state.
+ * Functions as a handle for a window that can receive input, and allows for the behavior of the
+ * input window to be configured.
* @hide
*/
public final class InputWindowHandle {
+
+ /**
+ * An internal annotation for all the {@link android.os.InputConfig} flags that can be
+ * specified to {@link #inputConfig} to control the behavior of an input window. Only the
+ * flags listed here are valid for use in Java.
+ *
+ * The default flag value is 0, which is what we expect for a normal application window. Adding
+ * a flag indicates that the window's behavior deviates from that of a normal application
+ * window.
+ *
+ * The flags are defined as an AIDL enum to keep it in sync with native code.
+ * {@link android.os.InputConfig} flags that are not listed here should not be used in Java, and
+ * are only meant to be used in native code.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = {
+ InputConfig.DEFAULT,
+ InputConfig.NO_INPUT_CHANNEL,
+ InputConfig.NOT_FOCUSABLE,
+ InputConfig.NOT_TOUCHABLE,
+ InputConfig.PREVENT_SPLITTING,
+ InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
+ InputConfig.IS_WALLPAPER,
+ InputConfig.PAUSE_DISPATCHING,
+ InputConfig.TRUSTED_OVERLAY,
+ InputConfig.WATCH_OUTSIDE_TOUCH,
+ InputConfig.SLIPPERY,
+ InputConfig.DISABLE_USER_ACTIVITY,
+ InputConfig.SPY,
+ InputConfig.INTERCEPTS_STYLUS,
+ })
+ public @interface InputConfigFlags {}
+
// Pointer to the native input window handle.
// This field is lazily initialized via JNI.
@SuppressWarnings("unused")
@@ -56,7 +93,8 @@ public final class InputWindowHandle {
// The window name.
public String name;
- // Window layout params attributes. (WindowManager.LayoutParams)
+ // Window layout params attributes. (WindowManager.LayoutParams)
+ // These values do not affect any input configurations. Use {@link #inputConfig} instead.
public int layoutParamsFlags;
public int layoutParamsType;
@@ -78,20 +116,9 @@ public final class InputWindowHandle {
// Window touchable region.
public final Region touchableRegion = new Region();
- // Window is visible.
- public boolean visible;
-
- // Window can be focused.
- public boolean focusable;
-
- // Window has wallpaper. (window is the current wallpaper target)
- public boolean hasWallpaper;
-
- // Input event dispatching is paused.
- public boolean paused;
-
- // Window is trusted overlay.
- public boolean trustedOverlay;
+ // Flags that specify the behavior of this input window. See {@link #InputConfigFlags}.
+ @InputConfigFlags
+ public int inputConfig;
// What effect this window has on touch occlusion if it lets touches pass through
// By default windows will block touches if they are untrusted and from a different UID due to
@@ -105,25 +132,21 @@ public final class InputWindowHandle {
// Owner package of the window
public String packageName;
- // Window input features.
- public int inputFeatures;
-
- // Display this input is on.
+ // Display this input window is on.
public int displayId;
/**
- * Crops the touchable region to the bounds of the surface provided.
+ * Crops the {@link #touchableRegion} to the bounds of the surface provided.
*
- * This can be used in cases where the window is not
- * {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the
- * bounds of a parent window. That is the window should receive touch events outside its
- * window but be limited to its stack bounds, such as in the case of split screen.
+ * This can be used in cases where the window should be constrained to the bounds of a parent
+ * window. That is, the window should receive touch events outside its window frame, but be
+ * limited to its stack bounds, such as in the case of split screen.
*/
public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
/**
- * Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
- * the handle is {@code null}, the bounds of the surface associated with this window is used
+ * Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}.
+ * If the handle is {@code null}, the bounds of the surface associated with this window is used
* as the touchable region.
*/
public boolean replaceTouchableRegionWithCrop;
@@ -147,7 +170,6 @@ public final class InputWindowHandle {
.append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
.append(frameRight).append(",").append(frameBottom).append("]")
.append(", touchableRegion=").append(touchableRegion)
- .append(", visible=").append(visible)
.append(", scaleFactor=").append(scaleFactor)
.append(", transform=").append(transform)
.append(", windowToken=").append(windowToken)
@@ -165,11 +187,11 @@ public final class InputWindowHandle {
}
/**
- * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any
- * touchable region provided.
+ * Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl}
+ * and ignore the value of {@link #touchableRegion}.
*
- * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds
- * to the current surface.
+ * @param bounds surface to set the touchable region to. Set to {@code null} to set the
+ * touchable region as the current surface bounds.
*/
public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
setTouchableRegionCrop(bounds);
@@ -195,4 +217,17 @@ public final class InputWindowHandle {
window = IWindow.Stub.asInterface(windowToken);
return window;
}
+
+ /**
+ * Set the provided inputConfig flag values.
+ * @param inputConfig the flag values to change
+ * @param value the provided flag values are set when true, and cleared when false
+ */
+ public void setInputConfig(@InputConfigFlags int inputConfig, boolean value) {
+ if (value) {
+ this.inputConfig |= inputConfig;
+ return;
+ }
+ this.inputConfig &= ~inputConfig;
+ }
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 0ef585478346..cc93adc32541 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1877,7 +1877,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
float x, float y, float pressure, float size, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
return obtain(downTime, eventTime, action, x, y, pressure, size, metaState,
- xPrecision, yPrecision, deviceId, edgeFlags, InputDevice.SOURCE_UNKNOWN,
+ xPrecision, yPrecision, deviceId, edgeFlags, InputDevice.SOURCE_CLASS_POINTER,
DEFAULT_DISPLAY);
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9aa243b241f7..413855639d09 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -51,6 +51,7 @@ import com.android.internal.view.SurfaceCallbackHelper;
import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
/**
* Provides a dedicated drawing surface embedded inside of a view hierarchy.
@@ -133,9 +134,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private boolean mDisableBackgroundLayer = false;
/**
- * We use this lock to protect access to mSurfaceControl and
- * SurfaceViewPositionUpdateListener#mPositionChangedTransaction. Both are accessed on the UI
- * thread and the render thread.
+ * We use this lock to protect access to mSurfaceControl. Both are accessed on the UI
+ * thread and the render thread via RenderNode.PositionUpdateListener#positionLost.
*/
final Object mSurfaceControlLock = new Object();
final Rect mTmpRect = new Rect();
@@ -224,12 +224,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private final SurfaceControl.Transaction mFrameCallbackTransaction =
new SurfaceControl.Transaction();
- /**
- * A temporary transaction holder that should only be used when applying right away. There
- * should be no assumption about thread safety for this transaction.
- */
- private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
-
private int mParentSurfaceSequenceId;
private RemoteAccessibilityController mRemoteAccessibilityController =
@@ -397,8 +391,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- private void performDrawFinished(Transaction t) {
- mSyncTransaction.merge(t);
+ private void performDrawFinished(@Nullable Transaction t) {
+ if (t != null) {
+ mSyncTransaction.merge(t);
+ }
if (mPendingReportDraws > 0) {
mDrawFinished = true;
@@ -760,7 +756,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mBlastBufferQueue = null;
}
- Transaction transaction = new Transaction();
+ final Transaction transaction = new Transaction();
if (mSurfaceControl != null) {
transaction.remove(mSurfaceControl);
mSurfaceControl = null;
@@ -790,22 +786,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
// synchronously otherwise we may see flickers.
// When the listener is updated, we will get at least a single position update call so we can
// guarantee any changes we post will be applied.
- private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight,
- Transaction geometryTransaction) {
+ private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight) {
if (mPositionListener != null) {
mRenderNode.removePositionUpdateListener(mPositionListener);
- synchronized (mSurfaceControlLock) {
- geometryTransaction = mPositionListener.getTransaction().merge(geometryTransaction);
- }
}
- mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight,
- geometryTransaction);
+ mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight);
mRenderNode.addPositionUpdateListener(mPositionListener);
}
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
boolean creating, boolean sizeChanged, boolean hintChanged,
- Transaction geometryTransaction) {
+ Transaction surfaceUpdateTransaction) {
boolean realSizeChanged = false;
mSurfaceLock.lock();
@@ -820,59 +811,60 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
// SurfaceChangedCallback to update the relative z. This is needed so that
// we do not change the relative z before the server is ready to swap the
// parent surface.
- if (creating || (mParentSurfaceSequenceId == viewRoot.getSurfaceSequenceId())) {
- updateRelativeZ(mTmpTransaction);
+ if (creating) {
+ updateRelativeZ(surfaceUpdateTransaction);
+ if (mSurfacePackage != null) {
+ reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage);
+ }
}
mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
if (mViewVisibility) {
- geometryTransaction.show(mSurfaceControl);
+ surfaceUpdateTransaction.show(mSurfaceControl);
} else {
- geometryTransaction.hide(mSurfaceControl);
+ surfaceUpdateTransaction.hide(mSurfaceControl);
}
- if (mSurfacePackage != null) {
- reparentSurfacePackage(mTmpTransaction, mSurfacePackage);
- }
- updateBackgroundVisibility(mTmpTransaction);
- updateBackgroundColor(mTmpTransaction);
+
+ updateBackgroundVisibility(surfaceUpdateTransaction);
+ updateBackgroundColor(surfaceUpdateTransaction);
if (mUseAlpha) {
float alpha = getFixedAlpha();
- mTmpTransaction.setAlpha(mSurfaceControl, alpha);
+ surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
mSurfaceAlpha = alpha;
}
- geometryTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
+ surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
if ((sizeChanged || hintChanged) && !creating) {
- setBufferSize(geometryTransaction);
+ setBufferSize(surfaceUpdateTransaction);
}
if (sizeChanged || creating || !isHardwareAccelerated()) {
- onSetSurfacePositionAndScaleRT(geometryTransaction, mSurfaceControl,
- mScreenRect.left, /*positionLeft*/
- mScreenRect.top /*positionTop*/ ,
- mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
- mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
// Set a window crop when creating the surface or changing its size to
// crop the buffer to the surface size since the buffer producer may
// use SCALING_MODE_SCALE and submit a larger size than the surface
// size.
if (mClipSurfaceToBounds && mClipBounds != null) {
- geometryTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
+ surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
} else {
- geometryTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
+ surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
}
- geometryTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
+ surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
if (isHardwareAccelerated()) {
// This will consume the passed in transaction and the transaction will be
// applied on a render worker thread.
- replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight,
- geometryTransaction);
+ replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
+ } else {
+ onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
+ mScreenRect.left /*positionLeft*/,
+ mScreenRect.top /*positionTop*/,
+ mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
+ mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
}
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
@@ -884,8 +876,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
}
}
- mTmpTransaction.merge(geometryTransaction);
- mTmpTransaction.apply();
+ applyTransactionOnVriDraw(surfaceUpdateTransaction);
updateEmbeddedAccessibilityMatrix();
mSurfaceFrame.left = 0;
@@ -993,17 +984,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
// Collect all geometry changes and apply these changes on the RenderThread worker
// via the RenderNode.PositionUpdateListener.
- final Transaction geometryTransaction = new Transaction();
+ final Transaction surfaceUpdateTransaction = new Transaction();
if (creating) {
updateOpaqueFlag();
final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
- createBlastSurfaceControls(viewRoot, name, geometryTransaction);
+ createBlastSurfaceControls(viewRoot, name, surfaceUpdateTransaction);
} else if (mSurfaceControl == null) {
return;
}
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
- translator, creating, sizeChanged, hintChanged, geometryTransaction);
+ translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
@@ -1050,16 +1041,24 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
callbacks = getSurfaceCallbacks();
}
- final Transaction t = new Transaction();
- if (viewRoot.wasRelayoutRequested()) {
- mBlastBufferQueue.setSyncTransaction(t,
- false /* acquireSingleBuffer */);
+ final boolean wasRelayoutRequested = viewRoot.wasRelayoutRequested();
+ if (wasRelayoutRequested && (mBlastBufferQueue != null)) {
+ mBlastBufferQueue.syncNextTransaction(
+ false /* acquireSingleBuffer */,
+ this::onDrawFinished);
}
mPendingReportDraws++;
viewRoot.drawPending();
SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
- mBlastBufferQueue.setSyncTransaction(null);
- onDrawFinished(t);
+ if (mBlastBufferQueue != null) {
+ mBlastBufferQueue.stopContinuousSyncTransaction();
+ }
+ // If relayout was requested, then a callback from BBQ will
+ // be invoked with the sync transaction. onDrawFinished will be
+ // called in there
+ if (!wasRelayoutRequested) {
+ onDrawFinished(null);
+ }
});
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
}
@@ -1139,7 +1138,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
*
*/
private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name,
- Transaction geometryTransaction) {
+ Transaction surfaceUpdateTransaction) {
if (mSurfaceControl == null) {
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setName(name)
@@ -1162,11 +1161,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
.build();
} else {
// update blast layer
- mTmpTransaction
+ surfaceUpdateTransaction
.setOpaque(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
.setSecure(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.SECURE) != 0)
- .show(mBlastSurfaceControl)
- .apply();
+ .show(mBlastSurfaceControl);
}
if (mBackgroundControl == null) {
@@ -1191,7 +1189,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
}
- private void onDrawFinished(Transaction t) {
+ private void onDrawFinished(@Nullable Transaction t) {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " "
+ "finishedDrawing");
@@ -1213,7 +1211,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
*
* @hide
*/
- protected void onSetSurfacePositionAndScaleRT(@NonNull Transaction transaction,
+ protected void onSetSurfacePositionAndScale(@NonNull Transaction transaction,
@NonNull SurfaceControl surface, int positionLeft, int positionTop,
float postScaleX, float postScaleY) {
transaction.setPosition(surface, positionLeft, positionTop);
@@ -1226,12 +1224,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (mSurfaceControl == null) {
return;
}
- onSetSurfacePositionAndScaleRT(mTmpTransaction, mSurfaceControl,
+ final Transaction transaction = new Transaction();
+ onSetSurfacePositionAndScale(transaction, mSurfaceControl,
mScreenRect.left, /*positionLeft*/
mScreenRect.top/*positionTop*/ ,
mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
- mTmpTransaction.apply();
+ applyTransactionOnVriDraw(transaction);
+ invalidate();
}
/**
@@ -1253,52 +1253,43 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- private Rect mRTLastReportedPosition = new Rect();
- private Point mRTLastReportedSurfaceSize = new Point();
+ private final Rect mRTLastReportedPosition = new Rect();
+ private final Point mRTLastReportedSurfaceSize = new Point();
private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
- int mRtSurfaceWidth = -1;
- int mRtSurfaceHeight = -1;
+ private final int mRtSurfaceWidth;
+ private final int mRtSurfaceHeight;
private final SurfaceControl.Transaction mPositionChangedTransaction =
new SurfaceControl.Transaction();
- boolean mPendingTransaction = false;
- SurfaceViewPositionUpdateListener(int surfaceWidth, int surfaceHeight,
- @Nullable Transaction t) {
+ SurfaceViewPositionUpdateListener(int surfaceWidth, int surfaceHeight) {
mRtSurfaceWidth = surfaceWidth;
mRtSurfaceHeight = surfaceHeight;
- if (t != null) {
- mPositionChangedTransaction.merge(t);
- mPendingTransaction = true;
- }
}
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
- synchronized(mSurfaceControlLock) {
- if (mSurfaceControl == null) {
- return;
- }
- if (mRTLastReportedPosition.left == left
- && mRTLastReportedPosition.top == top
- && mRTLastReportedPosition.right == right
- && mRTLastReportedPosition.bottom == bottom
- && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
- && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight
- && !mPendingTransaction) {
- return;
+ if (mRTLastReportedPosition.left == left
+ && mRTLastReportedPosition.top == top
+ && mRTLastReportedPosition.right == right
+ && mRTLastReportedPosition.bottom == bottom
+ && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
+ && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight) {
+ return;
+ }
+ try {
+ if (DEBUG_POSITION) {
+ Log.d(TAG, String.format(
+ "%d updateSurfacePosition RenderWorker, frameNr = %d, "
+ + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
+ System.identityHashCode(SurfaceView.this), frameNumber,
+ left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight));
}
- try {
- if (DEBUG_POSITION) {
- Log.d(TAG, String.format(
- "%d updateSurfacePosition RenderWorker, frameNr = %d, "
- + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
- System.identityHashCode(SurfaceView.this), frameNumber,
- left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight));
- }
+ synchronized (mSurfaceControlLock) {
+ if (mSurfaceControl == null) return;
mRTLastReportedPosition.set(left, top, right, bottom);
mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight);
- onSetSurfacePositionAndScaleRT(mPositionChangedTransaction, mSurfaceControl,
+ onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl,
mRTLastReportedPosition.left /*positionLeft*/,
mRTLastReportedPosition.top /*positionTop*/,
mRTLastReportedPosition.width()
@@ -1306,13 +1297,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mRTLastReportedPosition.height()
/ (float) mRtSurfaceHeight /*postScaleY*/);
if (mViewVisibility) {
+ // b/131239825
mPositionChangedTransaction.show(mSurfaceControl);
}
- applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
- mPendingTransaction = false;
- } catch (Exception ex) {
- Log.e(TAG, "Exception from repositionChild", ex);
}
+ applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
+ } catch (Exception ex) {
+ Log.e(TAG, "Exception from repositionChild", ex);
}
}
@@ -1336,28 +1327,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mRTLastReportedPosition.setEmpty();
mRTLastReportedSurfaceSize.set(-1, -1);
- /**
- * positionLost can be called while UI thread is un-paused so we
- * need to hold the lock here.
- */
+ // positionLost can be called while UI thread is un-paused.
synchronized (mSurfaceControlLock) {
- if (mPendingTransaction) {
- Log.w(TAG, System.identityHashCode(SurfaceView.this)
- + "Pending transaction cleared.");
- mPositionChangedTransaction.clear();
- mPendingTransaction = false;
- }
- if (mSurfaceControl == null) {
- return;
- }
+ if (mSurfaceControl == null) return;
+ // b/131239825
mRtTransaction.hide(mSurfaceControl);
applyOrMergeTransaction(mRtTransaction, frameNumber);
}
}
-
- public Transaction getTransaction() {
- return mPositionChangedTransaction;
- }
}
private SurfaceViewPositionUpdateListener mPositionListener = null;
@@ -1404,8 +1381,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
* @hide
*/
public void setResizeBackgroundColor(int bgColor) {
- setResizeBackgroundColor(mTmpTransaction, bgColor);
- mTmpTransaction.apply();
+ final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+ setResizeBackgroundColor(transaction, bgColor);
+ applyTransactionOnVriDraw(transaction);
+ invalidate();
}
/**
@@ -1824,7 +1803,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
/**
* @hide
*/
- public void syncNextFrame(Transaction t) {
- mBlastBufferQueue.setSyncTransaction(t);
+ public void syncNextFrame(Consumer<Transaction> t) {
+ mBlastBufferQueue.syncNextTransaction(t);
}
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 5775944b4e97..ebc409e470e9 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -1104,6 +1104,7 @@ public class ViewConfiguration {
* clear, or -1 if Views should not set themselves as preferred to keep clear.
* @hide
*/
+ @TestApi
public int getPreferKeepClearForFocusDelay() {
return mPreferKeepClearForFocusDelay;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 760e021bd4ab..bde761e59620 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -804,15 +804,6 @@ public final class ViewRootImpl implements ViewParent,
}
/**
- * This is only used on the RenderThread when handling a blast sync. Specifically, it's only
- * used when calling {@link BLASTBufferQueue#setSyncTransaction(Transaction)} and then merged
- * with a tmp transaction on the Render Thread. The tmp transaction is then merged into
- * {@link #mSurfaceChangedTransaction} on the UI Thread, avoiding any threading issues.
- */
- private final SurfaceControl.Transaction mRtBLASTSyncTransaction =
- new SurfaceControl.Transaction();
-
- /**
* Keeps track of the last frame number that was attempted to draw. Should only be accessed on
* the RenderThread.
*/
@@ -4175,43 +4166,49 @@ public final class ViewRootImpl implements ViewParent,
+ " didProduceBuffer=" + didProduceBuffer);
}
- final Transaction tmpTransaction = new Transaction();
- tmpTransaction.merge(mRtBLASTSyncTransaction);
-
// If frame wasn't drawn, clear out the next transaction so it doesn't affect the next
// draw attempt. The next transaction and transaction complete callback were only set
// for the current draw attempt.
+ final Transaction pendingTransactions;
if (!didProduceBuffer) {
- mBlastBufferQueue.setSyncTransaction(null);
+ mBlastBufferQueue.syncNextTransaction(null);
// Get the transactions that were sent to mergeWithNextTransaction since the
// frame didn't draw on this vsync. It's possible the frame will draw later, but
// it's better to not be sync than to block on a frame that may never come.
- Transaction pendingTransactions = mBlastBufferQueue.gatherPendingTransactions(
+ pendingTransactions = mBlastBufferQueue.gatherPendingTransactions(
mRtLastAttemptedDrawFrameNum);
- tmpTransaction.merge(pendingTransactions);
- }
- if (!useBlastSync && !reportNextDraw) {
- tmpTransaction.apply();
+ if (!useBlastSync && !reportNextDraw) {
+ pendingTransactions.apply();
+ }
+ } else {
+ pendingTransactions = null;
}
-
// Post at front of queue so the buffer can be processed immediately and allow RT
// to continue processing new buffers. If RT tries to process buffers before the sync
// buffer is applied, the new buffers will not get acquired and could result in a
// deadlock. UI thread would wait on RT, but RT would be blocked waiting for a free
// buffer.
mHandler.postAtFrontOfQueue(() -> {
- if (useBlastSync) {
- mSurfaceChangedTransaction.merge(tmpTransaction);
+ if (!didProduceBuffer && useBlastSync) {
+ mSurfaceChangedTransaction.merge(pendingTransactions);
if (blastSyncConsumer != null) {
blastSyncConsumer.accept(mSurfaceChangedTransaction);
}
}
- tmpTransaction.close();
- if (reportNextDraw) {
+ // This is to ensure pendingDrawFinished is only called exactly one time per draw
+ // attempt when reportNextDraw is true. Since, we sometimes create a sync
+ // transaction callback, the callback will handle calling pendingDrawFinished.
+ // However, there are cases where the transaction callback may not be called.
+ // 1. If useBlastSync is false, then we know that a sync transaction callback was
+ // not created so we won't invoke pendingDrawFinished there.
+ // 2. If the draw didn't produce a frame, didProduceBuffer == false, then we know
+ // the sync transaction callback will not be invoked even if one was set up.
+ if (reportNextDraw && (!didProduceBuffer || !useBlastSync)) {
pendingDrawFinished();
}
});
+
};
}
@@ -4294,7 +4291,19 @@ public final class ViewRootImpl implements ViewParent,
// Frame callbacks will always occur after submitting draw requests and before
// the draw actually occurs. This will ensure that we set the next transaction
// for the frame that's about to get drawn and not on a previous frame.
- mBlastBufferQueue.setSyncTransaction(mRtBLASTSyncTransaction);
+ mBlastBufferQueue.syncNextTransaction(
+ t -> {
+ mHandler.postAtFrontOfQueue(() -> {
+ mSurfaceChangedTransaction.merge(t);
+ if (blastSyncConsumer != null) {
+ blastSyncConsumer.accept(mSurfaceChangedTransaction);
+ }
+
+ if (reportNextDraw) {
+ pendingDrawFinished();
+ }
+ });
+ });
}
return createFrameCommitCallbackForSync(useBlastSync, reportNextDraw,
@@ -10928,24 +10937,23 @@ public final class ViewRootImpl implements ViewParent,
+ frame + ".");
}
- final Transaction t = new Transaction();
-
// If the syncResults are SYNC_LOST_SURFACE_REWARD_IF_FOUND or
// SYNC_CONTEXT_IS_STOPPED it means nothing will draw. There's no need to set up
// any blast sync or commit callback, and the code should directly call
// pendingDrawFinished.
if ((syncResult
& (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
- t.merge(mBlastBufferQueue.gatherPendingTransactions(frame));
- syncBufferCallback.onBufferReady(t);
+ syncBufferCallback.onBufferReady(
+ mBlastBufferQueue.gatherPendingTransactions(frame));
return null;
}
- mBlastBufferQueue.setSyncTransaction(t);
if (DEBUG_BLAST) {
Log.d(mTag, "Setting up sync and frameCommitCallback");
}
+ mBlastBufferQueue.syncNextTransaction(t -> syncBufferCallback.onBufferReady(t));
+
return didProduceBuffer -> {
if (DEBUG_BLAST) {
Log.d(mTag, "Received frameCommittedCallback"
@@ -10957,15 +10965,14 @@ public final class ViewRootImpl implements ViewParent,
// the next draw attempt. The next transaction and transaction complete callback
// were only set for the current draw attempt.
if (!didProduceBuffer) {
- mBlastBufferQueue.setSyncTransaction(null);
+ mBlastBufferQueue.syncNextTransaction(null);
// Gather the transactions that were sent to mergeWithNextTransaction
// since the frame didn't draw on this vsync. It's possible the frame will
// draw later, but it's better to not be sync than to block on a frame that
// may never come.
- t.merge(mBlastBufferQueue.gatherPendingTransactions(frame));
+ syncBufferCallback.onBufferReady(
+ mBlastBufferQueue.gatherPendingTransactions(frame));
}
-
- syncBufferCallback.onBufferReady(t);
};
}
});
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index dbfae46a6e72..45169efd7d35 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -106,7 +106,6 @@ import android.graphics.Region;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.IInputConstants;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -3360,8 +3359,7 @@ public interface WindowManager extends ViewManager {
*
* @hide
*/
- public static final int INPUT_FEATURE_NO_INPUT_CHANNEL =
- IInputConstants.InputFeature.NO_INPUT_CHANNEL;
+ public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 1 << 0;
/**
* When this window has focus, does not call user activity for all input events so
@@ -3374,58 +3372,43 @@ public interface WindowManager extends ViewManager {
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY =
- IInputConstants.InputFeature.DISABLE_USER_ACTIVITY;
+ public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 1 << 1;
/**
* An input spy window. This window will receive all pointer events within its touchable
- * area, but will will not stop events from being sent to other windows below it in z-order.
+ * area, but will not stop events from being sent to other windows below it in z-order.
* An input event will be dispatched to all spy windows above the top non-spy window at the
* event's coordinates.
- * @hide
- */
- public static final int INPUT_FEATURE_SPY =
- IInputConstants.InputFeature.SPY;
-
- /**
- * When used with the window flag {@link #FLAG_NOT_TOUCHABLE}, this window will continue
- * to receive events from a stylus device within its touchable region. All other pointer
- * events, such as from a mouse or touchscreen, will be dispatched to the windows behind it.
- *
- * This input feature has no effect when the window flag {@link #FLAG_NOT_TOUCHABLE} is
- * not set.
- *
- * The window must be a trusted overlay to use this input feature.
- *
- * @see #FLAG_NOT_TOUCHABLE
*
* @hide
*/
- public static final int INPUT_FEATURE_INTERCEPTS_STYLUS =
- IInputConstants.InputFeature.INTERCEPTS_STYLUS;
+ @RequiresPermission(permission.MONITOR_INPUT)
+ public static final int INPUT_FEATURE_SPY = 1 << 2;
/**
* An internal annotation for flags that can be specified to {@link #inputFeatures}.
*
+ * NOTE: These are not the same as {@link android.os.InputConfig} flags.
+ *
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "INPUT_FEATURE_" }, value = {
- INPUT_FEATURE_NO_INPUT_CHANNEL,
- INPUT_FEATURE_DISABLE_USER_ACTIVITY,
- INPUT_FEATURE_SPY,
- INPUT_FEATURE_INTERCEPTS_STYLUS,
+ @IntDef(flag = true, prefix = {"INPUT_FEATURE_"}, value = {
+ INPUT_FEATURE_NO_INPUT_CHANNEL,
+ INPUT_FEATURE_DISABLE_USER_ACTIVITY,
+ INPUT_FEATURE_SPY,
})
- public @interface InputFeatureFlags {}
+ public @interface InputFeatureFlags {
+ }
/**
- * Control special features of the input subsystem.
+ * Control a set of features of the input subsystem that are exposed to the app process.
+ *
+ * WARNING: Do NOT use {@link android.os.InputConfig} flags! This must be set to flag values
+ * included in {@link InputFeatureFlags}.
*
- * @see #INPUT_FEATURE_NO_INPUT_CHANNEL
- * @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
- * @see #INPUT_FEATURE_SPY
- * @see #INPUT_FEATURE_INTERCEPTS_STYLUS
* @hide
+ * @see InputFeatureFlags
*/
@InputFeatureFlags
@UnsupportedAppUsage
@@ -4845,10 +4828,6 @@ public interface WindowManager extends ViewManager {
inputFeatures &= ~INPUT_FEATURE_SPY;
features.add("INPUT_FEATURE_SPY");
}
- if ((inputFeatures & INPUT_FEATURE_INTERCEPTS_STYLUS) != 0) {
- inputFeatures &= ~INPUT_FEATURE_INTERCEPTS_STYLUS;
- features.add("INPUT_FEATURE_INTERCEPTS_STYLUS");
- }
if (inputFeatures != 0) {
features.add(Integer.toHexString(inputFeatures));
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index aeef76c3d048..0008aa64efa4 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -4487,8 +4487,8 @@ public class AccessibilityNodeInfo implements Parcelable {
case R.id.accessibilityActionDragDrop:
return "ACTION_DROP";
default: {
- if (action == R.id.accessibilityActionShowSuggestions) {
- return "ACTION_SHOW_SUGGESTIONS";
+ if (action == R.id.accessibilityActionShowTextSuggestions) {
+ return "ACTION_SHOW_TEXT_SUGGESTIONS";
}
return "ACTION_UNKNOWN";
}
@@ -5189,34 +5189,10 @@ public class AccessibilityNodeInfo implements Parcelable {
new AccessibilityAction(R.id.accessibilityActionDragCancel);
/**
- * Action to perform a left swipe.
- */
- @NonNull public static final AccessibilityAction ACTION_SWIPE_LEFT =
- new AccessibilityAction(R.id.accessibilityActionSwipeLeft);
-
- /**
- * Action to perform a right swipe.
- */
- @NonNull public static final AccessibilityAction ACTION_SWIPE_RIGHT =
- new AccessibilityAction(R.id.accessibilityActionSwipeRight);
-
- /**
- * Action to perform an up swipe.
- */
- @NonNull public static final AccessibilityAction ACTION_SWIPE_UP =
- new AccessibilityAction(R.id.accessibilityActionSwipeUp);
-
- /**
- * Action to perform a down swipe.
- */
- @NonNull public static final AccessibilityAction ACTION_SWIPE_DOWN =
- new AccessibilityAction(R.id.accessibilityActionSwipeDown);
-
- /**
* Action to show suggestions for editable text.
*/
- @NonNull public static final AccessibilityAction ACTION_SHOW_SUGGESTIONS =
- new AccessibilityAction(R.id.accessibilityActionShowSuggestions);
+ @NonNull public static final AccessibilityAction ACTION_SHOW_TEXT_SUGGESTIONS =
+ new AccessibilityAction(R.id.accessibilityActionShowTextSuggestions);
private final int mActionId;
private final CharSequence mLabel;
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index 69ad739608b2..fd336a27bb67 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -31,6 +31,7 @@ import android.view.MotionEvent;
import android.view.View;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.InlineSuggestionsRequestInfo;
@@ -105,14 +106,13 @@ public interface InputMethod {
* current IME.
* @param configChanges {@link InputMethodInfo#getConfigChanges()} declared by IME.
* @param stylusHwSupported {@link InputMethodInfo#supportsStylusHandwriting()} declared by IME.
- * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
- * shown while the IME is shown.
+ * @param navButtonFlags The initial state of {@link InputMethodNavButtonFlags}.
* @hide
*/
@MainThread
default void initializeInternal(IBinder token,
IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
- boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags) {
attachToken(token);
}
@@ -231,8 +231,7 @@ public interface InputMethod {
* the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as
* long as your implementation of {@link InputMethod} relies on such
* IPCs
- * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
- * shown while the IME is shown.
+ * @param navButtonFlags {@link InputMethodNavButtonFlags} in the initial state of this session.
* @see #startInput(InputConnection, EditorInfo)
* @see #restartInput(InputConnection, EditorInfo)
* @see EditorInfo
@@ -241,7 +240,7 @@ public interface InputMethod {
@MainThread
default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
- @NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
if (restarting) {
restartInput(inputConnection, editorInfo);
} else {
@@ -250,15 +249,13 @@ public interface InputMethod {
}
/**
- * Notifies that whether the IME should show the IME switcher or not is being changed.
+ * Notifies that {@link InputMethodNavButtonFlags} have been updated.
*
- * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
- * shown while the IME is shown.
+ * @param navButtonFlags The new {@link InputMethodNavButtonFlags}.
* @hide
*/
@MainThread
- default void onShouldShowImeSwitcherWhenImeIsShownChanged(
- boolean shouldShowImeSwitcherWhenImeIsShown) {
+ default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 248025190b3e..da20e336627c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1919,10 +1919,17 @@ public final class InputMethodManager {
if (fallbackImm != null) {
fallbackImm.startStylusHandwriting(view);
}
+ Objects.requireNonNull(view);
+
+ if (Settings.Global.getInt(view.getContext().getContentResolver(),
+ Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 0) {
+ Log.d(TAG, "Ignoring startStylusHandwriting(view) as stylus handwriting is disabled");
+ return;
+ }
checkFocus();
synchronized (mH) {
- if (view == null || !hasServedByInputMethodLocked(view)) {
+ if (!hasServedByInputMethodLocked(view)) {
Log.w(TAG,
"Ignoring startStylusHandwriting() as view=" + view + " is not served.");
return;
@@ -3251,10 +3258,11 @@ public final class InputMethodManager {
* @return Something that is not well-defined.
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 204906124, maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+ publicAlternatives = "Use {@link android.view.WindowInsets} instead")
public int getInputMethodWindowVisibleHeight() {
try {
- return mService.getInputMethodWindowVisibleHeight();
+ return mService.getInputMethodWindowVisibleHeight(mClient);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
index ef04b2c52282..6de031628768 100644
--- a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
+++ b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
@@ -105,7 +105,7 @@ public final class SelectionToolbarManager {
private boolean isRemoteSelectionToolbarEnabled() {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SELECTION_TOOLBAR,
- REMOTE_SELECTION_TOOLBAR_ENABLED, true);
+ REMOTE_SELECTION_TOOLBAR_ENABLED, false);
}
/**
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 40b38c0d0c6a..3160057e062f 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1366,7 +1366,10 @@ public abstract class WebSettings {
* Sets the WebView's user-agent string. If the string is {@code null} or empty,
* the system default value will be used.
*
- * Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android
+ * <p>If the user-agent is overridden in this way, the values of the User-Agent Client Hints
+ * headers and {@code navigator.userAgentData} for this WebView will be empty.
+ *
+ * <p>Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android
* version, changing the user-agent while loading a web page causes WebView
* to initiate loading once again.
*
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index b00a3829f468..fbad38f27a23 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -6681,7 +6681,13 @@ public class RemoteViews implements Parcelable, Filter {
opts = ActivityOptions.makeBasic();
opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
- opts.setLaunchDisplayId(view.getDisplay().getDisplayId());
+ if (view.getDisplay() != null) {
+ opts.setLaunchDisplayId(view.getDisplay().getDisplayId());
+ } else {
+ // TODO(b/218409359): Remove once bug is fixed.
+ Log.w(LOG_TAG, "getLaunchOptions: view.getDisplay() is null!",
+ new Exception());
+ }
return Pair.create(intent, opts);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c207af53fab7..b076d399d44a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12313,7 +12313,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
info.addAction(AccessibilityNodeInfo.ACTION_CUT);
}
if (canReplace()) {
- info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_SUGGESTIONS);
+ info.addAction(
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_TEXT_SUGGESTIONS);
}
if (canShare()) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
@@ -12634,7 +12635,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
default: {
// New ids have static blocks to assign values, so they can't be used in a case
// block.
- if (action == R.id.accessibilityActionShowSuggestions) {
+ if (action == R.id.accessibilityActionShowTextSuggestions) {
return isFocused() && canReplace() && onTextContextMenuItem(ID_REPLACE);
}
return super.performAccessibilityActionInternal(action, arguments);
diff --git a/core/java/android/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java
index 9712311aab7c..e4f483a29343 100644
--- a/core/java/android/widget/inline/InlineContentView.java
+++ b/core/java/android/widget/inline/InlineContentView.java
@@ -230,8 +230,9 @@ public class InlineContentView extends ViewGroup {
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes) {
+ // b/219807628
@Override
- protected void onSetSurfacePositionAndScaleRT(
+ protected void onSetSurfacePositionAndScale(
@NonNull SurfaceControl.Transaction transaction,
@NonNull SurfaceControl surface, int positionLeft, int positionTop,
float postScaleX, float postScaleY) {
@@ -248,7 +249,7 @@ public class InlineContentView extends ViewGroup {
postScaleX = InlineContentView.this.getScaleX();
postScaleY = InlineContentView.this.getScaleY();
- super.onSetSurfacePositionAndScaleRT(transaction, surface, positionLeft,
+ super.onSetSurfacePositionAndScale(transaction, surface, positionLeft,
positionTop, postScaleX, postScaleY);
}
};
diff --git a/core/java/android/window/SurfaceSyncer.java b/core/java/android/window/SurfaceSyncer.java
index a5930757cae6..0c32219f79a0 100644
--- a/core/java/android/window/SurfaceSyncer.java
+++ b/core/java/android/window/SurfaceSyncer.java
@@ -343,35 +343,20 @@ public class SurfaceSyncer {
@Override
public void onReadyToSync(SyncBufferCallback syncBufferCallback) {
- Transaction mTransaction = sTransactionFactory.get();
- mFrameCallbackConsumer.accept(new SurfaceViewFrameCallback() {
- @Override
- public void onFrameStarted() {
- mSurfaceView.syncNextFrame(mTransaction);
- }
-
- @Override
- public void onFrameComplete() {
- syncBufferCallback.onBufferReady(mTransaction);
- }
- });
+ mFrameCallbackConsumer.accept(
+ () -> mSurfaceView.syncNextFrame(syncBufferCallback::onBufferReady));
}
}
/**
* A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
- * implement onFrameStarted and onFrameComplete when trying to sync the SurfaceView. This is to
- * ensure the sync knows when the frame is ready to add to the sync.
+ * implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
+ * knows when the frame is ready to add to the sync.
*/
public interface SurfaceViewFrameCallback {
/**
* Called when the SurfaceView is going to render a frame
*/
void onFrameStarted();
-
- /**
- * Called when the SurfaceView has finished rendering a frame.
- */
- void onFrameComplete();
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index e336e96d577e..fd5eac8071bd 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1603,6 +1603,11 @@ public class ResolverActivity extends Activity implements
List<DisplayResolveInfo> otherProfileList =
mMultiProfilePagerAdapter.getInactiveListAdapter().mDisplayList;
+ if (sameProfileList.isEmpty()) {
+ Log.d(TAG, "No targets in the current profile");
+ return false;
+ }
+
if (otherProfileList.size() != 1) {
Log.d(TAG, "Found " + otherProfileList.size() + " resolvers in the other profile");
return false;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java b/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java
new file mode 100644
index 000000000000..728a42907cc4
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java
@@ -0,0 +1,49 @@
+/*
+ * 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.internal.inputmethod;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+
+/**
+ * A set of flags notified from {@link com.android.server.inputmethod.InputMethodManagerService} to
+ * {@link android.inputmethodservice.InputMethodService} regarding how
+ * {@link android.inputmethodservice.NavigationBarController} should behave.
+ *
+ * <p>These flags will take effect when and only when
+ * {@link android.inputmethodservice.InputMethodService#canImeRenderGesturalNavButtons} returns
+ * {@code true}.</p>
+ */
+@Retention(SOURCE)
+@IntDef(flag = true, value = {
+ InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR,
+ InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN,
+})
+public @interface InputMethodNavButtonFlags {
+ /**
+ * When set, the IME process needs to render and handle the navigation bar buttons such as the
+ * back button and the IME switcher button.
+ */
+ int IME_DRAWS_IME_NAV_BAR = 1;
+ /**
+ * When set, the IME switcher icon needs to be shown on the navigation bar.
+ */
+ int SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN = 2;
+}
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index ec95baae8c19..2784da00a02e 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -106,6 +106,7 @@ public class VpnConfig implements Parcelable {
public boolean allowIPv6;
public boolean isMetered = true;
public boolean requiresInternetValidation = false;
+ public boolean excludeLocalRoutes = false;
public Network[] underlyingNetworks;
public ProxyInfo proxyInfo;
@@ -133,6 +134,7 @@ public class VpnConfig implements Parcelable {
allowIPv6 = other.allowIPv6;
isMetered = other.isMetered;
requiresInternetValidation = other.requiresInternetValidation;
+ excludeLocalRoutes = other.excludeLocalRoutes;
underlyingNetworks = other.underlyingNetworks != null ? Arrays.copyOf(
other.underlyingNetworks, other.underlyingNetworks.length) : null;
proxyInfo = other.proxyInfo;
@@ -192,6 +194,7 @@ public class VpnConfig implements Parcelable {
out.writeInt(allowIPv6 ? 1 : 0);
out.writeInt(isMetered ? 1 : 0);
out.writeInt(requiresInternetValidation ? 1 : 0);
+ out.writeInt(excludeLocalRoutes ? 1 : 0);
out.writeTypedArray(underlyingNetworks, flags);
out.writeParcelable(proxyInfo, flags);
}
@@ -220,6 +223,7 @@ public class VpnConfig implements Parcelable {
config.allowIPv6 = in.readInt() != 0;
config.isMetered = in.readInt() != 0;
config.requiresInternetValidation = in.readInt() != 0;
+ config.excludeLocalRoutes = in.readInt() != 0;
config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
config.proxyInfo = in.readParcelable(null, android.net.ProxyInfo.class);
return config;
@@ -253,7 +257,8 @@ public class VpnConfig implements Parcelable {
.append(", allowIPv4=").append(allowIPv4)
.append(", allowIPv6=").append(allowIPv6)
.append(", isMetered=").append(isMetered)
- .append(", requiresInternetValidation").append(requiresInternetValidation)
+ .append(", requiresInternetValidation=").append(requiresInternetValidation)
+ .append(", excludeLocalRoutes=").append(excludeLocalRoutes)
.append(", underlyingNetworks=").append(Arrays.toString(underlyingNetworks))
.append(", proxyInfo=").append(proxyInfo)
.append("}")
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 37c96e71a0a8..7ee1f17b34df 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -312,9 +312,9 @@ public class TransitionAnimation {
/** Load animation by attribute Id from android package. */
@Nullable
- public Animation loadDefaultAnimationAttr(int animAttr) {
+ public Animation loadDefaultAnimationAttr(int animAttr, boolean translucent) {
return loadAnimationAttr(DEFAULT_PACKAGE, mDefaultWindowAnimationStyleResId, animAttr,
- false /* translucent */);
+ translucent);
}
@Nullable
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 9163b6d6215e..1d60c501a88b 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -70,7 +70,7 @@ interface IStatusBarService
void onPanelRevealed(boolean clearNotificationEffects, int numItems);
void onPanelHidden();
// Mark current notifications as "seen" and stop ringing, vibrating, blinking.
- void clearNotificationEffects();
+ oneway void clearNotificationEffects();
void onNotificationClick(String key, in NotificationVisibility nv);
void onNotificationActionClick(String key, int actionIndex, in Notification.Action action, in NotificationVisibility nv, boolean generatedByAssistant);
void onNotificationError(String pkg, String tag, int id,
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index d2bc3442ed36..273c5f170812 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -37,8 +37,7 @@ import com.android.internal.view.InlineSuggestionsRequestInfo;
*/
oneway interface IInputMethod {
void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
- int configChanges, boolean stylusHwSupported,
- boolean shouldShowImeSwitcherWhenImeIsShown);
+ int configChanges, boolean stylusHwSupported, int navigationBarFlags);
void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
in IInlineSuggestionsRequestCallback cb);
@@ -48,10 +47,9 @@ oneway interface IInputMethod {
void unbindInput();
void startInput(in IBinder startInputToken, in IInputContext inputContext,
- in EditorInfo attribute, boolean restarting,
- boolean shouldShowImeSwitcherWhenImeIsShown);
+ in EditorInfo attribute, boolean restarting, int navigationBarFlags);
- void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown);
+ void onNavButtonFlagsChanged(int navButtonFlags);
void createSession(in InputChannel channel, IInputSessionCallback callback);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 0df3e870b80c..c5346b95440b 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -67,7 +67,7 @@ interface IInputMethodManager {
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
// This is kept due to @UnsupportedAppUsage.
// TODO(Bug 113914148): Consider removing this.
- int getInputMethodWindowVisibleHeight();
+ int getInputMethodWindowVisibleHeight(in IInputMethodClient client);
oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible);
/** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index 3be0eb88a91f..c0f7b41d116d 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -35,6 +35,18 @@ static struct {
jmethodID ctor;
} gTransactionClassInfo;
+struct {
+ jmethodID accept;
+} gTransactionConsumer;
+
+static JNIEnv* getenv(JavaVM* vm) {
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
+ }
+ return env;
+}
+
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
jboolean updateDestinationFrame) {
ScopedUtfChars name(env, jName);
@@ -55,11 +67,51 @@ static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
queue->getSurface(includeSurfaceControlHandle));
}
-static void nativeSetSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr,
- jboolean acquireSingleBuffer) {
+class JGlobalRefHolder {
+public:
+ JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
+
+ virtual ~JGlobalRefHolder() {
+ getenv(mVm)->DeleteGlobalRef(mObject);
+ mObject = nullptr;
+ }
+
+ jobject object() { return mObject; }
+ JavaVM* vm() { return mVm; }
+
+private:
+ JGlobalRefHolder(const JGlobalRefHolder&) = delete;
+ void operator=(const JGlobalRefHolder&) = delete;
+
+ JavaVM* mVm;
+ jobject mObject;
+};
+
+static void nativeSyncNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jobject callback,
+ jboolean acquireSingleBuffer) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
- auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
- queue->setSyncTransaction(transaction, acquireSingleBuffer);
+ JavaVM* vm = nullptr;
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+ if (!callback) {
+ queue->syncNextTransaction(nullptr, acquireSingleBuffer);
+ } else {
+ auto globalCallbackRef =
+ std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback));
+ queue->syncNextTransaction(
+ [globalCallbackRef](SurfaceComposerClient::Transaction* t) {
+ JNIEnv* env = getenv(globalCallbackRef->vm());
+ env->CallVoidMethod(globalCallbackRef->object(), gTransactionConsumer.accept,
+ env->NewObject(gTransactionClassInfo.clazz,
+ gTransactionClassInfo.ctor,
+ reinterpret_cast<jlong>(t)));
+ },
+ acquireSingleBuffer);
+ }
+}
+
+static void nativeStopContinuousSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ queue->stopContinuousSyncTransaction();
}
static void nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width,
@@ -104,7 +156,8 @@ static const JNINativeMethod gMethods[] = {
{"nativeCreate", "(Ljava/lang/String;Z)J", (void*)nativeCreate},
{"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
- {"nativeSetSyncTransaction", "(JJZ)V", (void*)nativeSetSyncTransaction},
+ {"nativeSyncNextTransaction", "(JLjava/util/function/Consumer;Z)V", (void*)nativeSyncNextTransaction},
+ {"nativeStopContinuousSyncTransaction", "(J)V", (void*)nativeStopContinuousSyncTransaction},
{"nativeUpdate", "(JJJJI)V", (void*)nativeUpdate},
{"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction},
{"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
@@ -123,6 +176,10 @@ int register_android_graphics_BLASTBufferQueue(JNIEnv* env) {
gTransactionClassInfo.clazz = MakeGlobalRefOrDie(env, transactionClazz);
gTransactionClassInfo.ctor =
GetMethodIDOrDie(env, gTransactionClassInfo.clazz, "<init>", "(J)V");
+
+ jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
+ gTransactionConsumer.accept =
+ GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
return 0;
}
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index f453d1f06e22..db92310f2a26 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -23,6 +23,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include <binder/IPCThreadState.h>
+#include <ftl/cast.h>
#include <gui/SurfaceControl.h>
#include <gui/WindowInfo.h>
#include <nativehelper/JNIHelp.h>
@@ -63,16 +64,11 @@ static struct {
jfieldID surfaceInset;
jfieldID scaleFactor;
jfieldID touchableRegion;
- jfieldID visible;
- jfieldID focusable;
- jfieldID hasWallpaper;
- jfieldID paused;
- jfieldID trustedOverlay;
jfieldID touchOcclusionMode;
jfieldID ownerPid;
jfieldID ownerUid;
jfieldID packageName;
- jfieldID inputFeatures;
+ jfieldID inputConfig;
jfieldID displayId;
jfieldID replaceTouchableRegionWithCrop;
WeakRefHandleField touchableRegionSurfaceControl;
@@ -162,64 +158,8 @@ bool NativeInputWindowHandle::updateInfo() {
mInfo.layoutParamsFlags = flags;
mInfo.layoutParamsType = type;
- using InputConfig = gui::WindowInfo::InputConfig;
- // Determine the value for each of the InputConfig flags. We rely on a switch statement and
- // -Wswitch-enum to give us a build error if we forget to explicitly handle an InputConfig flag.
- mInfo.inputConfig = InputConfig::NONE;
- InputConfig enumerationStart = InputConfig::NONE;
- switch (enumerationStart) {
- case InputConfig::NONE:
- FALLTHROUGH_INTENDED;
- case InputConfig::NOT_VISIBLE:
- if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.visible) == JNI_FALSE) {
- mInfo.inputConfig |= InputConfig::NOT_VISIBLE;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::NOT_FOCUSABLE:
- if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.focusable) == JNI_FALSE) {
- mInfo.inputConfig |= InputConfig::NOT_FOCUSABLE;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::NOT_TOUCHABLE:
- if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
- mInfo.inputConfig |= InputConfig::NOT_TOUCHABLE;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::PREVENT_SPLITTING:
- if (!flags.test(WindowInfo::Flag::SPLIT_TOUCH)) {
- mInfo.inputConfig |= InputConfig::PREVENT_SPLITTING;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER:
- if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasWallpaper) == JNI_TRUE) {
- mInfo.inputConfig |= InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::IS_WALLPAPER:
- if (type == WindowInfo::Type::WALLPAPER) {
- mInfo.inputConfig |= InputConfig::IS_WALLPAPER;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::PAUSE_DISPATCHING:
- if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.paused) == JNI_TRUE) {
- mInfo.inputConfig |= InputConfig::PAUSE_DISPATCHING;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::TRUSTED_OVERLAY:
- if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.trustedOverlay) == JNI_TRUE) {
- mInfo.inputConfig |= InputConfig::TRUSTED_OVERLAY;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::WATCH_OUTSIDE_TOUCH:
- if (flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
- mInfo.inputConfig |= InputConfig::WATCH_OUTSIDE_TOUCH;
- }
- FALLTHROUGH_INTENDED;
- case InputConfig::SLIPPERY:
- if (flags.test(WindowInfo::Flag::SLIPPERY)) {
- mInfo.inputConfig |= InputConfig::SLIPPERY;
- }
- }
+ mInfo.inputConfig = static_cast<gui::WindowInfo::InputConfig>(
+ env->GetIntField(obj, gInputWindowHandleClassInfo.inputConfig));
mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
@@ -228,8 +168,6 @@ bool NativeInputWindowHandle::updateInfo() {
mInfo.ownerUid = env->GetIntField(obj,
gInputWindowHandleClassInfo.ownerUid);
mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
- mInfo.inputFeatures = static_cast<WindowInfo::Feature>(
- env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures));
mInfo.displayId = env->GetIntField(obj,
gInputWindowHandleClassInfo.displayId);
@@ -359,17 +297,6 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.touchableRegion,
regionObj.get());
- using InputConfig = gui::WindowInfo::InputConfig;
- env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.visible,
- !windowInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
- env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.focusable,
- !windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
- env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.hasWallpaper,
- windowInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
- env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.paused,
- windowInfo.inputConfig.test(InputConfig::PAUSE_DISPATCHING));
- env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.trustedOverlay,
- windowInfo.inputConfig.test(InputConfig::TRUSTED_OVERLAY));
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
static_cast<int32_t>(windowInfo.touchOcclusionMode));
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
@@ -377,8 +304,11 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
packageName.get());
- env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputFeatures,
- static_cast<int32_t>(windowInfo.inputFeatures.get()));
+
+ const auto inputConfig = windowInfo.inputConfig.get();
+ static_assert(sizeof(inputConfig) == sizeof(int32_t));
+ env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputConfig,
+ static_cast<int32_t>(inputConfig));
float transformVals[9];
for (int i = 0; i < 9; i++) {
@@ -481,19 +411,6 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
"touchableRegion", "Landroid/graphics/Region;");
- GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
- "visible", "Z");
-
- GET_FIELD_ID(gInputWindowHandleClassInfo.focusable, clazz, "focusable", "Z");
-
- GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
- "hasWallpaper", "Z");
-
- GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
- "paused", "Z");
-
- GET_FIELD_ID(gInputWindowHandleClassInfo.trustedOverlay, clazz, "trustedOverlay", "Z");
-
GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
@@ -505,8 +422,7 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
"Ljava/lang/String;");
- GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
- "inputFeatures", "I");
+ GET_FIELD_ID(gInputWindowHandleClassInfo.inputConfig, clazz, "inputConfig", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
"displayId", "I");
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c67cbcbd23c..a6fbf094a030 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -235,9 +235,7 @@ void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int
void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp);
- DIR *d;
char proc_path[255];
- struct dirent *de;
if (!verifyGroup(env, grp)) {
return;
@@ -277,84 +275,8 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
}
}
- sprintf(proc_path, "/proc/%d/task", pid);
- if (!(d = opendir(proc_path))) {
- // If the process exited on us, don't generate an exception
- if (errno != ENOENT)
- signalExceptionForGroupError(env, errno, pid);
- return;
- }
-
- while ((de = readdir(d))) {
- int t_pid;
- int t_pri;
- std::string taskprofile;
-
- if (de->d_name[0] == '.')
- continue;
- t_pid = atoi(de->d_name);
-
- if (!t_pid) {
- ALOGE("Error getting pid for '%s'\n", de->d_name);
- continue;
- }
-
- t_pri = getpriority(PRIO_PROCESS, t_pid);
-
- if (t_pri <= ANDROID_PRIORITY_AUDIO) {
- int scheduler = sched_getscheduler(t_pid) & ~SCHED_RESET_ON_FORK;
- if ((scheduler == SCHED_FIFO) || (scheduler == SCHED_RR)) {
- // This task wants to stay in its current audio group so it can keep its budget
- // don't update its cpuset or cgroup
- continue;
- }
- }
-
- errno = 0;
- // grp == SP_BACKGROUND. Set background cpuset policy profile for all threads.
- if (grp == SP_BACKGROUND) {
- if (!SetTaskProfiles(t_pid, {"CPUSET_SP_BACKGROUND"}, true)) {
- signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
- break;
- }
- continue;
- }
-
- // grp != SP_BACKGROUND. Only change the cpuset cgroup for low priority thread, so it could
- // preserve it sched policy profile setting.
- if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
- switch (grp) {
- case SP_SYSTEM:
- taskprofile = "ServiceCapacityLow";
- break;
- case SP_RESTRICTED:
- taskprofile = "ServiceCapacityRestricted";
- break;
- case SP_FOREGROUND:
- case SP_AUDIO_APP:
- case SP_AUDIO_SYS:
- taskprofile = "ProcessCapacityHigh";
- break;
- case SP_TOP_APP:
- taskprofile = "ProcessCapacityMax";
- break;
- default:
- taskprofile = "ProcessCapacityNormal";
- break;
- }
- if (!SetTaskProfiles(t_pid, {taskprofile}, true)) {
- signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
- break;
- }
- // Change the cpuset policy profile for non-low priority thread according to the grp
- } else {
- if (!SetTaskProfiles(t_pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}, true)) {
- signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
- break;
- }
- }
- }
- closedir(d);
+ if (!SetProcessProfilesCached(0, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}))
+ signalExceptionForGroupError(env, errno ? errno : EPERM, pid);
}
void android_os_Process_setProcessFrozen(
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 248db76da71d..0c05da551c8f 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -45,7 +45,7 @@ using android::zygote::ZygoteFailure;
// WARNING: Knows a little about the wire protocol used to communicate with Zygote.
// TODO: Fix error handling.
-constexpr size_t MAX_COMMAND_BYTES = 12200;
+constexpr size_t MAX_COMMAND_BYTES = 32768;
constexpr size_t NICE_NAME_BYTES = 50;
// A buffer optionally bundled with a file descriptor from which we can fill it.
@@ -273,8 +273,6 @@ class NativeCommandBuffer {
char mBuffer[MAX_COMMAND_BYTES];
};
-static_assert(sizeof(NativeCommandBuffer) < 3 * 4096);
-
static int buffersAllocd(0);
// Get a new NativeCommandBuffer. Can only be called once between freeNativeBuffer calls,
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 51e150e28437..57026d95ceb8 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -48,7 +48,6 @@ import "frameworks/base/core/proto/android/service/batterystats.proto";
import "frameworks/base/core/proto/android/service/diskstats.proto";
import "frameworks/base/core/proto/android/service/dropbox.proto";
import "frameworks/base/core/proto/android/service/graphicsstats.proto";
-import "frameworks/base/core/proto/android/service/netstats.proto";
import "frameworks/base/core/proto/android/service/notification.proto";
import "frameworks/base/core/proto/android/service/package.proto";
import "frameworks/base/core/proto/android/service/print.proto";
@@ -62,7 +61,8 @@ import "frameworks/base/core/proto/android/util/textdump.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
import "frameworks/base/proto/src/ipconnectivity.proto";
-import "packages/modules/Permission/service/proto/com/android/role/roleservice.proto";
+import "packages/modules/Connectivity/framework/proto/netstats.proto";
+import "packages/modules/Permission/service/proto/role_service.proto";
package android.os;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 3929027a4e94..0ade0934f2a6 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -53,6 +53,7 @@ message WindowManagerServiceDumpProto {
optional int32 last_orientation = 8 [(.android.typedef) = "android.content.pm.ActivityInfo.ScreenOrientation", deprecated=true];
optional int32 focused_display_id = 9;
optional bool hard_keyboard_available = 10;
+ optional bool window_frames_valid = 11;
}
/* represents RootWindowContainer object */
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
deleted file mode 100644
index ba2b6d6bd7e0..000000000000
--- a/core/proto/android/service/netstats.proto
+++ /dev/null
@@ -1,121 +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.
- */
-
-syntax = "proto2";
-package android.service;
-
-option java_multiple_files = true;
-option java_outer_classname = "NetworkStatsServiceProto";
-
-// Represents dumpsys from NetworkStatsService (netstats).
-message NetworkStatsServiceDumpProto {
- repeated NetworkInterfaceProto active_interfaces = 1;
-
- repeated NetworkInterfaceProto active_uid_interfaces = 2;
-
- // Device level network stats, which may include non-IP layer traffic.
- optional NetworkStatsRecorderProto dev_stats = 3;
-
- // IP-layer traffic stats.
- optional NetworkStatsRecorderProto xt_stats = 4;
-
- // Per-UID network stats.
- optional NetworkStatsRecorderProto uid_stats = 5;
-
- // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0).
- optional NetworkStatsRecorderProto uid_tag_stats = 6;
-}
-
-// Corresponds to NetworkStatsService.mActiveIfaces/mActiveUidIfaces.
-message NetworkInterfaceProto {
- // Name of the network interface (eg: wlan).
- optional string interface = 1;
-
- optional NetworkIdentitySetProto identities = 2;
-}
-
-// Corresponds to NetworkIdentitySet.
-message NetworkIdentitySetProto {
- repeated NetworkIdentityProto identities = 1;
-}
-
-// Corresponds to NetworkIdentity.
-message NetworkIdentityProto {
- // Constants from ConnectivityManager.TYPE_*.
- optional int32 type = 1;
-
- optional bool roaming = 4;
-
- optional bool metered = 5;
-
- optional bool default_network = 6;
-
- optional int32 oem_managed_network = 7;
-}
-
-// Corresponds to NetworkStatsRecorder.
-message NetworkStatsRecorderProto {
- optional int64 pending_total_bytes = 1;
-
- optional NetworkStatsCollectionProto complete_history = 2;
-}
-
-// Corresponds to NetworkStatsCollection.
-message NetworkStatsCollectionProto {
- repeated NetworkStatsCollectionStatsProto stats = 1;
-}
-
-// Corresponds to NetworkStatsCollection.mStats.
-message NetworkStatsCollectionStatsProto {
- optional NetworkStatsCollectionKeyProto key = 1;
-
- optional NetworkStatsHistoryProto history = 2;
-}
-
-// Corresponds to NetworkStatsCollection.Key.
-message NetworkStatsCollectionKeyProto {
- optional NetworkIdentitySetProto identity = 1;
-
- optional int32 uid = 2;
-
- optional int32 set = 3;
-
- optional int32 tag = 4;
-}
-
-// Corresponds to NetworkStatsHistory.
-message NetworkStatsHistoryProto {
- // Duration for this bucket in milliseconds.
- optional int64 bucket_duration_ms = 1;
-
- repeated NetworkStatsHistoryBucketProto buckets = 2;
-}
-
-// Corresponds to each bucket in NetworkStatsHistory.
-message NetworkStatsHistoryBucketProto {
- // Bucket start time in milliseconds since epoch.
- optional int64 bucket_start_ms = 1;
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-
- optional int64 operations = 6;
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d7744e377f12..fa9eba34d30b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2937,7 +2937,7 @@
<!-- @SystemApi @hide Allows an application to set the profile owners and the device owner.
This permission is not available to third party applications.-->
<permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
- android:protectionLevel="signature|role|setup"
+ android:protectionLevel="signature|role"
android:label="@string/permlab_manageProfileAndDeviceOwners"
android:description="@string/permdesc_manageProfileAndDeviceOwners" />
@@ -2946,6 +2946,10 @@
<permission android:name="android.permission.QUERY_ADMIN_POLICY"
android:protectionLevel="signature|role" />
+ <!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.-->
+ <permission android:name="android.permission.PROVISION_DEMO_DEVICE"
+ android:protectionLevel="signature|setup" />
+
<!-- @TestApi @hide Allows an application to reset the record of previous system update freeze
periods. -->
<permission android:name="android.permission.CLEAR_FREEZE_PERIOD"
@@ -3714,15 +3718,26 @@
android:protectionLevel="signature|privileged" />
<!-- ========================================= -->
- <!-- Permissions for SupplementalApi -->
+ <!-- Permissions for AdServices -->
<!-- ========================================= -->
<eat-comment />
- <!-- TODO(b/213488783): Update with correct names. -->
- <!-- Allows an application to access SupplementalApis. -->
- <permission android:name="android.permission.ACCESS_SUPPLEMENTAL_APIS"
- android:label="@string/permlab_accessSupplementalApi"
- android:description="@string/permdesc_accessSupplementalApi"
+ <!-- Allows an application to access AdServices Topics API. -->
+ <permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS"
+ android:label="@string/permlab_accessAdServicesTopics"
+ android:description="@string/permdesc_accessAdServicesTopics"
+ android:protectionLevel="normal" />
+
+ <!-- Allows an application to access AdServices Attribution APIs. -->
+ <permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION"
+ android:label="@string/permlab_accessAdServicesAttribution"
+ android:description="@string/permdesc_accessAdServicesAttribution"
+ android:protectionLevel="normal" />
+
+ <!-- Allows an application to access AdServices Custom Audiences APIs. -->
+ <permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES"
+ android:label="@string/permlab_accessAdServicesCustomAudiences"
+ android:description="@string/permdesc_accessAdServicesCustomAudiences"
android:protectionLevel="normal" />
<!-- ==================================== -->
@@ -6910,10 +6925,6 @@
android:resource="@xml/autofill_compat_accessibility_service" />
</service>
- <service android:name="com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy"
- android:permission="android.permission.BIND_JOB_SERVICE" >
- </service>
-
<service android:name="com.android.server.blob.BlobStoreIdleJobService"
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 4bea4d55e5ef..ca8b3f8aa070 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -26,6 +26,10 @@ toddke@google.com
tsuji@google.com
yamasani@google.com
+# Resources finalization
+per-file res/xml/public-staging.xml = file:/tools/aapt2/OWNERS
+per-file res/xml/public-final.xml = file:/tools/aapt2/OWNERS
+
# Multiuser
per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
diff --git a/core/res/res/anim-ldrtl/activity_close_enter.xml b/core/res/res/anim-ldrtl/activity_close_enter.xml
new file mode 100644
index 000000000000..6a699e7fcdfa
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_close_enter.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="1.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="0"
+ android:duration="450" />
+
+ <translate
+ android:fromXDelta="10%"
+ android:toXDelta="0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+
+ <extend
+ android:fromExtendLeft="10%"
+ android:fromExtendTop="0"
+ android:fromExtendRight="0"
+ android:fromExtendBottom="0"
+ android:toExtendLeft="10%"
+ android:toExtendTop="0"
+ android:toExtendRight="0"
+ android:toExtendBottom="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+</set> \ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/activity_close_exit.xml b/core/res/res/anim-ldrtl/activity_close_exit.xml
new file mode 100644
index 000000000000..06a0d6916f61
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_close_exit.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="35"
+ android:duration="83" />
+
+ <translate
+ android:fromXDelta="0"
+ android:toXDelta="-10%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+
+ <extend
+ android:fromExtendLeft="0"
+ android:fromExtendTop="0"
+ android:fromExtendRight="10%"
+ android:fromExtendBottom="0"
+ android:toExtendLeft="0"
+ android:toExtendTop="0"
+ android:toExtendRight="10%"
+ android:toExtendBottom="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+</set>
diff --git a/core/res/res/anim-ldrtl/activity_open_enter.xml b/core/res/res/anim-ldrtl/activity_open_enter.xml
new file mode 100644
index 000000000000..7b1829466884
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_open_enter.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+
+ <alpha
+ android:fromAlpha="0"
+ android:toAlpha="1.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="50"
+ android:duration="83" />
+
+ <translate
+ android:fromXDelta="-10%"
+ android:toXDelta="0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="450" />
+
+ <extend
+ android:fromExtendLeft="0"
+ android:fromExtendTop="0"
+ android:fromExtendRight="10%"
+ android:fromExtendBottom="0"
+ android:toExtendLeft="0"
+ android:toExtendTop="0"
+ android:toExtendRight="10%"
+ android:toExtendBottom="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+</set>
diff --git a/core/res/res/anim-ldrtl/activity_open_exit.xml b/core/res/res/anim-ldrtl/activity_open_exit.xml
new file mode 100644
index 000000000000..c29509ef1b2a
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_open_exit.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+
+ <alpha
+ android:fromAlpha="1.0"
+ android:toAlpha="1.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/standard_accelerate"
+ android:startOffset="0"
+ android:duration="450" />
+
+ <translate
+ android:fromXDelta="0"
+ android:toXDelta="10%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+
+ <extend
+ android:fromExtendLeft="10%"
+ android:fromExtendTop="0"
+ android:fromExtendRight="0"
+ android:fromExtendBottom="0"
+ android:toExtendLeft="10%"
+ android:toExtendTop="0"
+ android:toExtendRight="0"
+ android:toExtendBottom="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:startOffset="0"
+ android:duration="450" />
+</set> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_swap_horiz.xml b/core/res/res/drawable/ic_swap_horiz.xml
new file mode 100644
index 000000000000..e7517f9e8d91
--- /dev/null
+++ b/core/res/res/drawable/ic_swap_horiz.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M17,14L15.6,12.575L18.175,10H11V8H18.175L15.6,5.425L17,4L22,9ZM7,20L2,15L7,10L8.4,11.425L5.825,14H13V16H5.825L8.4,18.575Z" />
+</vector>
diff --git a/core/res/res/layout/user_switching_dialog.xml b/core/res/res/layout/user_switching_dialog.xml
index c80621092e22..2e041f5f2be2 100644
--- a/core/res/res/layout/user_switching_dialog.xml
+++ b/core/res/res/layout/user_switching_dialog.xml
@@ -18,10 +18,13 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/message"
style="?attr/textAppearanceListItem"
- android:layout_width="match_parent"
+ android:background="?attr/colorSurface"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
+ android:drawablePadding="12dp"
+ android:drawableTint="?attr/textColorPrimary"
android:paddingStart="?attr/dialogPreferredPadding"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="24dp"
- android:paddingBottom="24dp" /> \ No newline at end of file
+ android:paddingBottom="24dp" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bc271bfaa222..879fc9e6ceb7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2931,6 +2931,11 @@
<!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
<string name="config_appsAuthorizedForSharedAccounts" translatable="false">;com.android.settings;</string>
+ <!-- Settings intelligence package name -->
+ <string name="config_settingsIntelligencePackageName" translatable="false">
+ com.android.settings.intelligence
+ </string>
+
<!-- Flag indicating that the media framework should not allow changes or mute on any
stream or global volumes. -->
<bool name="config_useFixedVolume">false</bool>
@@ -5262,9 +5267,9 @@
<bool name="config_cecPowerStateChangeOnActiveSourceLost_userConfigurable">true</bool>
<bool name="config_cecPowerStateChangeOnActiveSourceLostNone_allowed">true</bool>
- <bool name="config_cecPowerStateChangeOnActiveSourceLostNone_default">true</bool>
+ <bool name="config_cecPowerStateChangeOnActiveSourceLostNone_default">false</bool>
<bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_allowed">true</bool>
- <bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default">false</bool>
+ <bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default">true</bool>
<bool name="config_cecSystemAudioControl_userConfigurable">true</bool>
<bool name="config_cecSystemAudioControlEnabled_allowed">true</bool>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 29eb0c0365b3..082acbe3443a 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -270,20 +270,8 @@
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_CANCEL}. -->
<item type="id" name="accessibilityActionDragCancel" />
- <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_LEFT}. -->
- <item type="id" name="accessibilityActionSwipeLeft" />
-
- <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_RIGHT}. -->
- <item type="id" name="accessibilityActionSwipeRight" />
-
- <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_UP}. -->
- <item type="id" name="accessibilityActionSwipeUp" />
-
- <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_DOWN}. -->
- <item type="id" name="accessibilityActionSwipeDown" />
-
- <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_SUGGESTIONS}. -->
- <item type="id" name="accessibilityActionShowSuggestions" />
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_TEXT_SUGGESTIONS}. -->
+ <item type="id" name="accessibilityActionShowTextSuggestions" />
<!-- View tag for remote views to store the index of the next child when adding nested remote views dynamically. -->
<item type="id" name="remote_views_next_child" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3467e1b40470..80664eb296af 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3211,8 +3211,6 @@
</staging-public-group-final>
<public type="attr" name="shouldUseDefaultUnfoldTransition" id="0x0101064c" />
- <public type="attr" name="lineBreakStyle" id="0x0101064d" />
- <public type="attr" name="lineBreakWordStyle" id="0x0101064e" />
<staging-public-group-final type="id" first-id="0x01fe0000">
<public name="accessibilityActionDragStart" />
@@ -3281,14 +3279,16 @@
<public name="intro" />
<public name="enableOnBackInvokedCallback" />
<public name="supportsInlineSuggestionsWithTouchExploration" />
+ <public name="lineBreakStyle" />
+ <public name="lineBreakWordStyle" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01de0000">
- <public name="accessibilityActionSwipeLeft" />
- <public name="accessibilityActionSwipeRight" />
- <public name="accessibilityActionSwipeUp" />
- <public name="accessibilityActionSwipeDown" />
- <public name="accessibilityActionShowSuggestions" />
+ <public name="removed_accessibilityActionSwipeLeft" />
+ <public name="removed_accessibilityActionSwipeRight" />
+ <public name="removed_accessibilityActionSwipeUp" />
+ <public name="removed_accessibilityActionSwipeDown" />
+ <public name="accessibilityActionShowTextSuggestions" />
<public name="inputExtractAction" />
<public name="inputExtractAccessories" />
</staging-public-group>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e64756119478..05ebef9bf56f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -234,9 +234,9 @@
<!-- Displayed to tell the user that they should switch their network preference. -->
<string name="NetworkPreferenceSwitchSummary">Try changing preferred network. Tap to change.</string>
<!-- Displayed to tell the user that emergency calls might not be available. -->
- <string name="EmergencyCallWarningTitle">Emergency calling unavailable</string>
+ <string name="EmergencyCallWarningTitle">Emergency calls may be unavailable</string>
<!-- Displayed to tell the user that emergency calls might not be available. -->
- <string name="EmergencyCallWarningSummary">Can\u2019t make emergency calls over Wi\u2011Fi</string>
+ <string name="EmergencyCallWarningSummary"><xliff:g id="spn" example="Operator">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details.</string>
<!-- Telephony notification channel name for a channel containing network alert notifications. -->
<string name="notification_channel_network_alert">Alerts</string>
@@ -4095,10 +4095,20 @@
<!-- Description of an application permission that lets it query all other packages. [CHAR LIMIT=NONE] -->
<string name="permdesc_queryAllPackages">Allows an app to see all installed packages.</string>
- <!-- Title of an application permission that lets it access SupplementalApis. [CHAR LIMIT=NONE] -->
- <string name="permlab_accessSupplementalApi">access SupplementalApis</string>
- <!-- Description of an application permission that lets it access SupplementalApis. [CHAR LIMIT=NONE]-->
- <string name="permdesc_accessSupplementalApi">Allows an application to access SupplementalApis.</string>
+ <!-- Title of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE] -->
+ <string name="permlab_accessAdServicesTopics">access AdServices Topics API</string>
+ <!-- Description of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE]-->
+ <string name="permdesc_accessAdServicesTopics">Allows an application to access AdServices Topics API.</string>
+
+ <!-- Title of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE] -->
+ <string name="permlab_accessAdServicesAttribution">access AdServices Attribution APIs</string>
+ <!-- Description of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE]-->
+ <string name="permdesc_accessAdServicesAttribution">Allows an application to access AdServices Attribution APIs.</string>
+
+ <!-- Title of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE] -->
+ <string name="permlab_accessAdServicesCustomAudiences">access AdServices Custom Audiences API</string>
+ <!-- Description of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE]-->
+ <string name="permdesc_accessAdServicesCustomAudiences">Allows an application to access AdServices Custom Audiences API.</string>
<!-- Shown in the tutorial for tap twice for zoom control. -->
<string name="tutorial_double_tap_to_zoom_message_short">Tap twice for zoom control</string>
@@ -4894,6 +4904,8 @@
<string name="user_logging_out_message">Logging out <xliff:g id="name" example="Bob">%1$s</xliff:g>\u2026</string>
<!-- Default name of the owner user [CHAR LIMIT=20] -->
<string name="owner_name" msgid="3879126011135546571">Owner</string>
+ <!-- Default name of the guest user [CHAR LIMIT=35] -->
+ <string name="guest_name">Guest</string>
<!-- Error message title [CHAR LIMIT=35] -->
<string name="error_message_title">Error</string>
<!-- Message informing user that the change was disallowed by an administrator. [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2112953d6962..2e1c6c2afc78 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1108,6 +1108,7 @@
<java-symbol type="string" name="media_route_status_not_available" />
<java-symbol type="string" name="media_route_status_in_use" />
<java-symbol type="string" name="owner_name" />
+ <java-symbol type="string" name="guest_name" />
<java-symbol type="string" name="config_chooseAccountActivity" />
<java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
<java-symbol type="string" name="config_chooserActivity" />
@@ -4763,4 +4764,6 @@
<java-symbol type="bool" name="config_bg_prompt_fgs_with_noti_to_bg_restricted" />
<java-symbol type="integer" name="config_bg_current_drain_exempted_types" />
<java-symbol type="bool" name="config_bg_current_drain_high_threshold_by_bg_location" />
+ <java-symbol type="drawable" name="ic_swap_horiz" />
+
</resources>
diff --git a/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb b/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb
deleted file mode 100644
index 373b8e4bd01f..000000000000
--- a/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb b/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb
deleted file mode 100644
index aa531d8b35bd..000000000000
--- a/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
index e690da2d0377..76e761a7616e 100644
--- a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
@@ -49,7 +49,7 @@ import java.util.concurrent.TimeUnit;
abstract class AbstractCrossUserContentResolverTest {
private static final int TIMEOUT_SERVICE_CONNECTION_SEC = 4;
private static final int TIMEOUT_CONTENT_CHANGE_SEC = 4;
- private static final int TIMEOUT_USER_UNLOCK_SEC = 4;
+ private static final int TIMEOUT_USER_UNLOCK_SEC = 10;
private Context mContext;
protected UserManager mUm;
diff --git a/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
index 1bc46a79f1c0..68d4cd4a97e7 100644
--- a/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
@@ -20,6 +20,7 @@ import android.content.pm.UserInfo;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
import androidx.test.filters.LargeTest;
@@ -36,6 +37,7 @@ import androidx.test.filters.LargeTest;
* Run: adb shell am instrument -e class android.content.ManagedUserContentResolverTest -w \
* com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
*/
+@Presubmit
@LargeTest
public class ManagedUserContentResolverTest extends AbstractCrossUserContentResolverTest {
@Override
diff --git a/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java b/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java
index dbe027800e3f..de4c5725c190 100644
--- a/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java
@@ -18,6 +18,7 @@ package android.content;
import android.content.pm.UserInfo;
import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
import androidx.test.filters.LargeTest;
@@ -34,6 +35,7 @@ import androidx.test.filters.LargeTest;
* Run: adb shell am instrument -e class android.content.SecondaryUserContentResolverTest -w \
* com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
*/
+@Presubmit
@LargeTest
public class SecondaryUserContentResolverTest extends AbstractCrossUserContentResolverTest {
@Override
diff --git a/core/tests/coretests/src/android/graphics/FontListParserTest.java b/core/tests/coretests/src/android/graphics/FontListParserTest.java
index 701e6194d4ee..479e52aab029 100644
--- a/core/tests/coretests/src/android/graphics/FontListParserTest.java
+++ b/core/tests/coretests/src/android/graphics/FontListParserTest.java
@@ -355,6 +355,27 @@ public final class FontListParserTest {
assertThat(config.getAliases()).isEmpty();
}
+ @Test
+ public void ignore() throws Exception {
+ String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<familyset>"
+ + " <family name='sans-serif'>"
+ + " <font>test.ttf</font>"
+ + " </family>"
+ + " <family lang='und-Zsye' ignore='true'>"
+ + " <font>emoji_legacy.ttf</font>"
+ + " </family>"
+ + " <family lang='und-Zsye'>"
+ + " <font>emoji.ttf</font>"
+ + " </family>"
+ + "</familyset>";
+ FontConfig config = readFamilies(xml, true /* include non-existing font files */);
+ List<FontConfig.FontFamily> families = config.getFontFamilies();
+ assertThat(families.size()).isEqualTo(2); // legacy one should be ignored.
+ assertThat(families.get(1).getFontList().get(0).getFile().getName())
+ .isEqualTo("emoji.ttf");
+ }
+
private FontConfig readFamilies(String xml, boolean allowNonExisting)
throws IOException, XmlPullParserException {
ByteArrayInputStream buffer = new ByteArrayInputStream(
diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
new file mode 100644
index 000000000000..fa7d7214d289
--- /dev/null
+++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
@@ -0,0 +1,312 @@
+/*
+ * 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.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for verifying the behavior of {@link IpcDataCache}. This test does
+ * not use any actual binder calls - it is entirely self-contained. This test also relies
+ * on the test mode of {@link IpcDataCache} because Android SELinux rules do
+ * not grant test processes the permission to set system properties.
+ * <p>
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:IpcDataCacheTest
+ */
+@SmallTest
+public class IpcDataCacheTest {
+
+ // Configuration for creating caches
+ private static final String MODULE = IpcDataCache.MODULE_TEST;
+ private static final String API = "testApi";
+
+ // This class is a proxy for binder calls. It contains a counter that increments
+ // every time the class is queried.
+ private static class ServerProxy {
+ // The number of times this class was queried.
+ private int mCount = 0;
+
+ // A single query. The key behavior is that the query count is incremented.
+ boolean query(int x) {
+ mCount++;
+ return value(x);
+ }
+
+ // Return the expected value of an input, without incrementing the query count.
+ boolean value(int x) {
+ return x % 3 == 0;
+ }
+
+ // Verify the count.
+ void verify(int x) {
+ assertEquals(x, mCount);
+ }
+ }
+
+ // The functions for querying the server.
+ private static class ServerQuery
+ extends IpcDataCache.QueryHandler<Integer, Boolean> {
+ private final ServerProxy mServer;
+
+ ServerQuery(ServerProxy server) {
+ mServer = server;
+ }
+
+ @Override
+ public Boolean apply(Integer x) {
+ return mServer.query(x);
+ }
+ @Override
+ public boolean shouldBypassCache(Integer x) {
+ return x % 13 == 0;
+ }
+ }
+
+ // Clear the test mode after every test, in case this process is used for other
+ // tests. This also resets the test property map.
+ @After
+ public void tearDown() throws Exception {
+ IpcDataCache.setTestMode(false);
+ }
+
+ // This test is disabled pending an sepolicy change that allows any app to set the
+ // test property.
+ @Test
+ public void testBasicCache() {
+
+ // A stand-in for the binder. The test verifies that calls are passed through to
+ // this class properly.
+ ServerProxy tester = new ServerProxy();
+
+ // Create a cache that uses simple arithmetic to computer its values.
+ IpcDataCache<Integer, Boolean> testCache =
+ new IpcDataCache<>(4, MODULE, API, "testCache1",
+ new ServerQuery(tester));
+
+ IpcDataCache.setTestMode(true);
+ testCache.testPropertyName();
+
+ tester.verify(0);
+ assertEquals(tester.value(3), testCache.query(3));
+ tester.verify(1);
+ assertEquals(tester.value(3), testCache.query(3));
+ tester.verify(2);
+ testCache.invalidateCache();
+ assertEquals(tester.value(3), testCache.query(3));
+ tester.verify(3);
+ assertEquals(tester.value(5), testCache.query(5));
+ tester.verify(4);
+ assertEquals(tester.value(5), testCache.query(5));
+ tester.verify(4);
+ assertEquals(tester.value(3), testCache.query(3));
+ tester.verify(4);
+
+ // Invalidate the cache, and verify that the next read on 3 goes to the server.
+ testCache.invalidateCache();
+ assertEquals(tester.value(3), testCache.query(3));
+ tester.verify(5);
+
+ // Test bypass. The query for 13 always bypasses the cache.
+ assertEquals(tester.value(12), testCache.query(12));
+ assertEquals(tester.value(13), testCache.query(13));
+ assertEquals(tester.value(14), testCache.query(14));
+ tester.verify(8);
+ assertEquals(tester.value(12), testCache.query(12));
+ assertEquals(tester.value(13), testCache.query(13));
+ assertEquals(tester.value(14), testCache.query(14));
+ tester.verify(9);
+ }
+
+ @Test
+ public void testDisableCache() {
+
+ // A stand-in for the binder. The test verifies that calls are passed through to
+ // this class properly.
+ ServerProxy tester = new ServerProxy();
+
+ // Three caches, all using the same system property but one uses a different name.
+ IpcDataCache<Integer, Boolean> cache1 =
+ new IpcDataCache<>(4, MODULE, API, "cacheA",
+ new ServerQuery(tester));
+ IpcDataCache<Integer, Boolean> cache2 =
+ new IpcDataCache<>(4, MODULE, API, "cacheA",
+ new ServerQuery(tester));
+ IpcDataCache<Integer, Boolean> cache3 =
+ new IpcDataCache<>(4, MODULE, API, "cacheB",
+ new ServerQuery(tester));
+
+ // Caches are enabled upon creation.
+ assertEquals(false, cache1.getDisabledState());
+ assertEquals(false, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Disable the cache1 instance. Only cache1 is disabled
+ cache1.disableInstance();
+ assertEquals(true, cache1.getDisabledState());
+ assertEquals(false, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Disable cache1. This will disable cache1 and cache2 because they share the
+ // same name. cache3 has a different name and will not be disabled.
+ cache1.disableForCurrentProcess();
+ assertEquals(true, cache1.getDisabledState());
+ assertEquals(true, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Create a new cache1. Verify that the new instance is disabled.
+ cache1 = new IpcDataCache<>(4, MODULE, API, "cacheA",
+ new ServerQuery(tester));
+ assertEquals(true, cache1.getDisabledState());
+
+ // Remove the record of caches being locally disabled. This is a clean-up step.
+ cache1.forgetDisableLocal();
+ assertEquals(true, cache1.getDisabledState());
+ assertEquals(true, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Create a new cache1. Verify that the new instance is not disabled.
+ cache1 = new IpcDataCache<>(4, MODULE, API, "cacheA",
+ new ServerQuery(tester));
+ assertEquals(false, cache1.getDisabledState());
+ }
+
+ private static class TestQuery
+ extends IpcDataCache.QueryHandler<Integer, String> {
+
+ private int mRecomputeCount = 0;
+
+ @Override
+ public String apply(Integer qv) {
+ mRecomputeCount += 1;
+ return "foo" + qv.toString();
+ }
+
+ int getRecomputeCount() {
+ return mRecomputeCount;
+ }
+ }
+
+ private static class TestCache extends IpcDataCache<Integer, String> {
+ private final TestQuery mQuery;
+
+ TestCache() {
+ this(MODULE, API);
+ }
+
+ TestCache(String module, String api) {
+ this(module, api, new TestQuery());
+ }
+
+ TestCache(String module, String api, TestQuery query) {
+ super(4, module, api, "testCache7", query);
+ mQuery = query;
+ setTestMode(true);
+ testPropertyName();
+ }
+
+ int getRecomputeCount() {
+ return mQuery.getRecomputeCount();
+ }
+ }
+
+ @Test
+ public void testCacheRecompute() {
+ TestCache cache = new TestCache();
+ cache.invalidateCache();
+ assertEquals(cache.isDisabled(), false);
+ assertEquals("foo5", cache.query(5));
+ assertEquals(1, cache.getRecomputeCount());
+ assertEquals("foo5", cache.query(5));
+ assertEquals(1, cache.getRecomputeCount());
+ assertEquals("foo6", cache.query(6));
+ assertEquals(2, cache.getRecomputeCount());
+ cache.invalidateCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(3, cache.getRecomputeCount());
+ // Invalidate the cache with a direct call to the property.
+ IpcDataCache.invalidateCache(MODULE, API);
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(4, cache.getRecomputeCount());
+ }
+
+ @Test
+ public void testCacheInitialState() {
+ TestCache cache = new TestCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(2, cache.getRecomputeCount());
+ cache.invalidateCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(3, cache.getRecomputeCount());
+ }
+
+ @Test
+ public void testCachePropertyUnset() {
+ final String UNSET_API = "otherApi";
+ TestCache cache = new TestCache(MODULE, UNSET_API);
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(2, cache.getRecomputeCount());
+ }
+
+ @Test
+ public void testCacheDisableState() {
+ TestCache cache = new TestCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(2, cache.getRecomputeCount());
+ cache.invalidateCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(3, cache.getRecomputeCount());
+ cache.disableSystemWide();
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(5, cache.getRecomputeCount());
+ cache.invalidateCache(); // Should not reenable
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(7, cache.getRecomputeCount());
+ }
+
+ @Test
+ public void testLocalProcessDisable() {
+ TestCache cache = new TestCache();
+ assertEquals(cache.isDisabled(), false);
+ cache.invalidateCache();
+ assertEquals("foo5", cache.query(5));
+ assertEquals(1, cache.getRecomputeCount());
+ assertEquals("foo5", cache.query(5));
+ assertEquals(1, cache.getRecomputeCount());
+ assertEquals(cache.isDisabled(), false);
+ cache.disableForCurrentProcess();
+ assertEquals(cache.isDisabled(), true);
+ assertEquals("foo5", cache.query(5));
+ assertEquals("foo5", cache.query(5));
+ assertEquals(3, cache.getRecomputeCount());
+ }
+}
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
index e6660f32f817..d01d29bda3d6 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
@@ -55,11 +55,7 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
protected static String OBB_FILE_1_CONTENTS_1 = "OneToOneThousandInts.bin";
protected static String OBB_FILE_2 = "obb_file2.obb";
protected static String OBB_FILE_3 = "obb_file3.obb";
- protected static String OBB_FILE_1_PASSWORD = "password1";
- protected static String OBB_FILE_1_ENCRYPTED = "obb_enc_file100_orig1.obb";
protected static String OBB_FILE_2_UNSIGNED = "obb_file2_nosign.obb";
- protected static String OBB_FILE_3_PASSWORD = "password3";
- protected static String OBB_FILE_3_ENCRYPTED = "obb_enc_file100_orig3.obb";
protected static String OBB_FILE_3_BAD_PACKAGENAME = "obb_file3_bad_packagename.obb";
protected static boolean FORCE = true;
@@ -227,22 +223,21 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
* Mounts an OBB file
*
* @param obbFilePath The full path to the OBB file to mount
- * @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
* @param expectedState The expected state resulting from trying to mount the OBB
* @return A {@link String} representing the normalized path to OBB file that was mounted
*/
- protected String mountObb(String obbFilePath, String key, int expectedState) {
- return doMountObb(obbFilePath, key, expectedState);
+ protected String mountObb(String obbFilePath, int expectedState) {
+ return doMountObb(obbFilePath, expectedState);
}
/**
- * Mounts an OBB file with default options (no encryption, mounting succeeds)
+ * Mounts an OBB file with default options.
*
* @param obbFilePath The full path to the OBB file to mount
* @return A {@link String} representing the normalized path to OBB file that was mounted
*/
protected String mountObb(String obbFilePath) {
- return doMountObb(obbFilePath, null, OnObbStateChangeListener.MOUNTED);
+ return doMountObb(obbFilePath, OnObbStateChangeListener.MOUNTED);
}
/**
@@ -279,13 +274,13 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
* @return true if the listener was signaled of a state change by the system; else a fail()
* is triggered if we timed out
*/
- protected String doMountObb_noThrow(String obbFilePath, String key, int expectedState) {
- Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
+ protected String doMountObb_noThrow(String obbFilePath, int expectedState) {
+ Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
ObbListener obbListener = new ObbListener();
- boolean success = mSm.mountObb(obbFilePath, key, obbListener);
+ boolean success = mSm.mountObb(obbFilePath, null, obbListener);
success &= obbFilePath.equals(doWaitForObbStateChange(obbListener));
success &= (expectedState == obbListener.state());
@@ -307,17 +302,16 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
* Mounts an OBB file without throwing and synchronously waits for it to finish mounting
*
* @param obbFilePath The full path to the OBB file to mount
- * @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
* @param expectedState The expected state resulting from trying to mount the OBB
* @return A {@link String} representing the actual normalized path to OBB file that was
* mounted, or null if the mounting failed
*/
- protected String doMountObb(String obbFilePath, String key, int expectedState) {
- Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
+ protected String doMountObb(String obbFilePath, int expectedState) {
+ Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
ObbListener obbListener = new ObbListener();
- assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, key, obbListener));
+ assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, null, obbListener));
assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
doWaitForObbStateChange(obbListener));
assertEquals("OBB mount state not what was expected!", expectedState,
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index 62f2ac28a601..ecd2f76a5160 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -83,58 +83,6 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
}
/**
- * Tests mounting a single encrypted OBB file and verifies its contents.
- */
- @LargeTest
- public void testMountSingleEncryptedObb() throws Exception {
- final File file = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
- String filePath = file.getAbsolutePath();
- mountObb(filePath, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
- verifyObb3Contents(filePath);
- unmountObb(filePath, DONT_FORCE);
- }
-
- /**
- * Tests mounting a single encrypted OBB file using an invalid password.
- */
- @LargeTest
- public void testMountSingleEncryptedObbInvalidPassword() throws Exception {
- final File file = createObbFile("bad password@$%#@^*(!&)", R.raw.obb_enc_file100_orig3);
- String filePath = file.getAbsolutePath();
- mountObb(filePath, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
- }
-
- /**
- * Tests simultaneously mounting 2 encrypted OBBs with different keys and verifies contents.
- */
- @LargeTest
- public void testMountTwoEncryptedObb() throws Exception {
- File file3 = null;
- File file1 = null;
- try {
- file3 = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
- String filePath3 = file3.getAbsolutePath();
- mountObb(filePath3, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
- verifyObb3Contents(filePath3);
-
- file1 = createObbFile(OBB_FILE_1_ENCRYPTED, R.raw.obb_enc_file100_orig1);
- String filePath1 = file1.getAbsolutePath();
- mountObb(filePath1, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.MOUNTED);
- verifyObb1Contents(filePath1);
-
- unmountObb(filePath3, DONT_FORCE);
- unmountObb(filePath1, DONT_FORCE);
- } finally {
- if (file3 != null) {
- file3.delete();
- }
- if (file1 != null) {
- file1.delete();
- }
- }
- }
-
- /**
* Tests mounting a single OBB that isn't signed.
*/
@LargeTest
@@ -142,7 +90,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
String filePath = file.getAbsolutePath();
try {
- mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+ mountObb(filePath, OnObbStateChangeListener.ERROR_INTERNAL);
fail("mountObb should've failed with an exception");
} catch (IllegalArgumentException e) {
// Expected
@@ -156,8 +104,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
public void testMountBadPackageNameObb() throws Exception {
final File file = createObbFile(OBB_FILE_3_BAD_PACKAGENAME, R.raw.obb_file3_bad_packagename);
String filePath = file.getAbsolutePath();
- mountObb(filePath, OBB_FILE_3_BAD_PACKAGENAME,
- OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+ mountObb(filePath, OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
}
/**
@@ -169,7 +116,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
String filePath = file.getAbsolutePath();
mountObb(filePath);
verifyObb1Contents(filePath);
- mountObb(filePath, null, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
+ mountObb(filePath, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
verifyObb1Contents(filePath);
unmountObb(filePath, DONT_FORCE);
}
diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java
index 78a8f7b3f32e..c4c983d24af9 100644
--- a/core/tests/coretests/src/android/view/MotionEventTest.java
+++ b/core/tests/coretests/src/android/view/MotionEventTest.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.InputDevice.SOURCE_CLASS_POINTER;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.TOOL_TYPE_FINGER;
@@ -214,4 +215,27 @@ public class MotionEventTest {
rotInvalid.transform(mat);
assertEquals(-1, rotInvalid.getSurfaceRotation());
}
+
+ @Test
+ public void testUsesPointerSourceByDefault() {
+ final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+ ACTION_DOWN, 0 /* x */, 0 /* y */, 0 /* metaState */);
+ assertTrue(event.isFromSource(SOURCE_CLASS_POINTER));
+ }
+
+ @Test
+ public void testLocationOffsetOnlyAppliedToNonPointerSources() {
+ final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+ ACTION_DOWN, 10 /* x */, 20 /* y */, 0 /* metaState */);
+ event.offsetLocation(40, 50);
+
+ // The offset should be applied since a pointer source is used by default.
+ assertEquals(50, (int) event.getX());
+ assertEquals(70, (int) event.getY());
+
+ // The offset should not be applied if the source is changed to a non-pointer source.
+ event.setSource(InputDevice.SOURCE_JOYSTICK);
+ assertEquals(10, (int) event.getX());
+ assertEquals(20, (int) event.getY());
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 2817728fd9ea..e7a23f262753 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -39,6 +39,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
import android.content.Intent;
import android.content.pm.ResolveInfo;
@@ -52,6 +53,7 @@ import android.widget.TextView;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.Espresso;
+import androidx.test.espresso.NoMatchingViewException;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
@@ -750,6 +752,34 @@ public class ResolverActivityTest {
}
@Test
+ public void testMiniResolver_noCurrentProfileTarget() {
+ ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsForTest(0);
+ List<ResolvedComponentInfo> workResolvedComponentInfos =
+ createResolvedComponentsForTest(1);
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ Intent sendIntent = createSendImageIntent();
+ sendIntent.setType("TestType");
+
+ mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+
+ // Need to ensure mini resolver doesn't trigger here.
+ assertNotMiniResolver();
+ }
+
+ private void assertNotMiniResolver() {
+ try {
+ onView(withId(R.id.open_cross_profile)).check(matches(isDisplayed()));
+ } catch (NoMatchingViewException e) {
+ return;
+ }
+ fail("Mini resolver present but shouldn't be");
+ }
+
+ @Test
public void testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown() {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3c64cf55eb50..deffa3a6fea6 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -237,27 +237,6 @@ applications that come with the platform
<permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
</privapp-permissions>
- <privapp-permissions package="com.android.providers.media.module">
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
- <permission name="android.permission.MANAGE_USERS"/>
- <permission name="android.permission.USE_RESERVED_DISK"/>
- <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
- <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
- <permission name="android.permission.WATCH_APPOPS"/>
- <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
- <permission name="android.permission.UPDATE_DEVICE_STATS"/>
- <!-- Permissions required for reading and logging compat changes -->
- <permission name="android.permission.LOG_COMPAT_CHANGE" />
- <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
- <permission name="android.permission.REGISTER_STATS_PULL_ATOM" />
- <!-- Permissions required for reading DeviceConfig -->
- <permission name="android.permission.READ_DEVICE_CONFIG" />
- <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/>
- <permission name="android.permission.MODIFY_QUIET_MODE"/>
- <!-- Permissions required to check if an app is in the foreground or not during IO -->
- <permission name="android.permission.PACKAGE_USAGE_STATS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.providers.telephony">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index e050e1784fac..84e949a18c52 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1328,6 +1328,9 @@
postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
</font>
</family>
+ <family lang="und-Zsye" ignore="true">
+ <font weight="400" style="normal">NotoColorEmojiLegacy.ttf</font>
+ </family>
<family lang="und-Zsye">
<font weight="400" style="normal">NotoColorEmoji.ttf</font>
</family>
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 369f20fb52a7..7f70e1cce6f5 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -16,10 +16,11 @@
package android.graphics;
-import android.annotation.Nullable;
import android.view.Surface;
import android.view.SurfaceControl;
+import java.util.function.Consumer;
+
/**
* @hide
*/
@@ -30,8 +31,9 @@ public final class BLASTBufferQueue {
private static native long nativeCreate(String name, boolean updateDestinationFrame);
private static native void nativeDestroy(long ptr);
private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
- private static native void nativeSetSyncTransaction(long ptr, long transactionPtr,
- boolean acquireSingleBuffer);
+ private static native void nativeSyncNextTransaction(long ptr,
+ Consumer<SurfaceControl.Transaction> callback, boolean acquireSingleBuffer);
+ private static native void nativeStopContinuousSyncTransaction(long ptr);
private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height,
int format);
private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr,
@@ -74,25 +76,39 @@ public final class BLASTBufferQueue {
}
/**
- * Send the transaction to BBQ so the next frame can be added and not applied immediately. This
- * gives the caller a chance to apply the transaction when it's ready.
- *
- * @param t The transaction to add the frame to. This can be null to clear the
- * transaction.
+ * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a
+ * transaction it created and will eventually send the transaction into the callback
+ * when it is ready.
+ * @param callback The callback invoked when the buffer has been added to the transaction. The
+ * callback will contain the transaction with the buffer.
* @param acquireSingleBuffer If true, only acquire a single buffer when processing frames. The
- * transaction will be cleared once a single buffer has been
+ * callback will be cleared once a single buffer has been
* acquired. If false, continue to acquire all buffers into the
- * transaction until setSyncTransaction is called again with a null
- * transaction.
+ * transaction until stopContinuousSyncTransaction is called.
+ */
+ public void syncNextTransaction(boolean acquireSingleBuffer,
+ Consumer<SurfaceControl.Transaction> callback) {
+ nativeSyncNextTransaction(mNativeObject, callback, acquireSingleBuffer);
+ }
+
+ /**
+ * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a
+ * transaction it created and will eventually send the transaction into the callback
+ * when it is ready.
+ * @param callback The callback invoked when the buffer has been added to the transaction. The
+ * callback will contain the transaction with the buffer.
*/
- public void setSyncTransaction(@Nullable SurfaceControl.Transaction t,
- boolean acquireSingleBuffer) {
- nativeSetSyncTransaction(mNativeObject, t == null ? 0 : t.mNativeObject,
- acquireSingleBuffer);
+ public void syncNextTransaction(Consumer<SurfaceControl.Transaction> callback) {
+ syncNextTransaction(true /* acquireSingleBuffer */, callback);
}
- public void setSyncTransaction(@Nullable SurfaceControl.Transaction t) {
- setSyncTransaction(t, true /* acquireSingleBuffer */);
+ /**
+ * Tell BBQ to stop acquiring buffers into a single transaction. BBQ will send the sync
+ * transaction callback after this has been called. This should only be used when
+ * syncNextTransaction was called with acquireSingleBuffer set to false.
+ */
+ public void stopContinuousSyncTransaction() {
+ nativeStopContinuousSyncTransaction(mNativeObject);
}
/**
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 96b33259e739..4bb16c6b8186 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -218,6 +218,7 @@ public class FontListParser {
final String name = parser.getAttributeValue(null, "name");
final String lang = parser.getAttributeValue("", "lang");
final String variant = parser.getAttributeValue(null, "variant");
+ final String ignore = parser.getAttributeValue(null, "ignore");
final List<FontConfig.Font> fonts = new ArrayList<>();
while (keepReading(parser)) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
@@ -240,7 +241,9 @@ public class FontListParser {
intVariant = FontConfig.FontFamily.VARIANT_ELEGANT;
}
}
- if (fonts.isEmpty()) {
+
+ boolean skip = (ignore != null && (ignore.equals("true") || ignore.equals("1")));
+ if (skip || fonts.isEmpty()) {
return null;
}
return new FontConfig.FontFamily(fonts, name, LocaleList.forLanguageTags(lang), intVariant);
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 2ff888b06dd8..6abe34b1d675 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -19,12 +19,228 @@ package android.graphics;
import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.NonNull;
+import android.view.Window;
import libcore.util.NativeAllocationRegistry;
/**
- * Shader that calculates per-pixel color via a user defined Android Graphics Shading Language
- * (AGSL) function.
+ * <p>A {@link RuntimeShader} calculates a per-pixel color based on the output of a user defined
+ * Android Graphics Shading Language (AGSL) function.</p>
+ *
+ * <h3>Android Graphics Shading Language</h3>
+ * <p>The AGSL syntax is very similar to OpenGL ES Shading Language, but there are some important
+ * differences that are highlighted here. Most of these differences are summed up in one basic fact:
+ * <b>With GPU shading languages, you are programming a stage of the GPU pipeline. With AGSL, you
+ * are programming a stage of the {@link Canvas} or {@link RenderNode} drawing pipeline.</b></p>
+ *
+ * <p>In particular, a GLSL fragment shader controls the entire behavior of the GPU between the
+ * rasterizer and the blending hardware. That shader does all of the work to compute a color, and
+ * the color it generates is exactly what is fed to the blending stage of the pipeline.</p>
+ *
+ * <p>In contrast, AGSL functions exist as part of a larger pipeline. When you issue a
+ * {@link Canvas} drawing operation, Android (generally) assembles a single GPU fragment shader to
+ * do all of the required work. This shader typically includes several pieces. For example, it might
+ * include:</p>
+ * <ul>
+ * <li>Evaluating whether a pixel falls inside or outside of the shape being drawn (or on the
+ * border, where it might apply antialiasing).</li>
+ * <li>Evaluating whether a pixel falls inside or outside of the clipping region (again, with
+ * possible antialiasing logic for border pixels).</li>
+ * <li>Logic for the {@link Shader}, {@link ColorFilter}, and {@link BlendMode} on the
+ * {@link Paint}.</li>
+ * <li>Color space conversion code, as part of Android’s color management.</li>
+ * </ul>
+ *
+ * <p>A {@link RuntimeShader}, like other {@link Shader} types, effectively contributes a function
+ * to the GPU’s fragment shader.</p>
+ *
+ * <h3>AGSL Shader Execution</h3>
+ * <p>Just like a GLSL shader, an AGSL shader begins execution in a main function. Unlike GLSL, the
+ * function receives as an input parameter the position of the pixel within the {@link Canvas} or
+ * {@link RenderNode} coordinate space (similar to gl_fragCoord) and returns the color to be shaded
+ * as a vec4 (similar to out vec4 color or gl_FragColor in GLSL).</p>
+ *
+ * <pre class="prettyprint">
+ * vec4 main(vec2 canvas_coordinates);
+ * </pre>
+ *
+ * <p>AGSL and GLSL use different coordinate spaces by default. In GLSL, the fragment coordinate
+ * (fragCoord) is relative to the lower left. AGSL matches the screen coordinate system of the
+ * Android {@link Canvas} which has its origin as the upper left corner. This means that the
+ * coordinates provided as a parameter in the main function are local to the canvas with the
+ * exception of any {@link Shader#getLocalMatrix(Matrix)} transformations applied to this shader.
+ * Additionally, if the shader is invoked by another using {@link #setInputShader(String, Shader)},
+ * then that parent shader may modify the input coordinates arbitrarily.</p>
+ *
+ * <h3>AGSL and Color Spaces</h3>
+ * <p>Android Graphics and by extension {@link RuntimeShader} are color managed. The working
+ * {@link ColorSpace} for an AGSL shader is defined to be the color space of the destination, which
+ * in most cases is determined by {@link Window#setColorMode(int)}.</p>
+ *
+ * <p>When authoring an AGSL shader, you won’t know what the working color space is. For many
+ * effects, this is fine because by default color inputs are automatically converted into the
+ * working color space. For certain effects, it may be important to do some math in a fixed, known
+ * color space. A common example is lighting – to get physically accurate lighting, math should be
+ * done in a linear color space. To help with this, AGSL provides two intrinsic functions that
+ * convert colors between the working color space and the
+ * {@link ColorSpace.Named#LINEAR_EXTENDED_SRGB} color space:
+ *
+ * <pre class="prettyprint">
+ * vec3 toLinearSrgb(vec3 color);
+ * vec3 fromLinearSrgb(vec3 color);</pre>
+ *
+ * <h3>AGSL and Premultiplied Alpha</h3>
+ * <p>When dealing with transparent colors, there are two (common) possible representations:
+ * straight (unassociated) alpha and premultiplied (associated) alpha. In ASGL the color returned
+ * by the main function is expected to be premultiplied. AGSL’s use of premultiplied alpha
+ * implies:
+ * </p>
+ *
+ * <ul>
+ * <li>If your AGSL shader will return transparent colors, be sure to multiply the RGB by A. The
+ * resulting color should be [R*A, G*A, B*A, A], not [R, G, B, A].</li>
+ * <li>For more complex shaders, you must understand which of your colors are premultiplied vs.
+ * straight. Many operations don’t make sense if you mix both kinds of color together.</li>
+ * </ul>
+ *
+ * <h3>Uniforms</h3>
+ * <p>AGSL, like GLSL, exposes the concept of uniforms. An AGSL uniform is defined as a read-only,
+ * global variable that is accessible by the AGSL code and is initialized by a number of setter
+ * methods on {@link RuntimeShader}. AGSL exposes two primitive uniform data types (float, int) and
+ * two specialized types (colors, shaders) that are outlined below.</p>
+ *
+ * <h4>Primitive Uniforms</h4>
+ * <p>There are two primitive uniform types supported by AGSL, float and int. For these types and
+ * uniforms representing a grouping of these types, like arrays and matrices, there are
+ * corresponding {@link RuntimeShader} methods to initialize them.
+ * <table border="2" width="85%" align="center" cellpadding="5">
+ * <thead>
+ * <tr><th>Java Type</th> <th>AGSL Type</th> <th>Method</th> </tr>
+ * </thead>
+ *
+ * <tbody>
+ * <tr>
+ * <td rowspan="4">Floats</td>
+ * <td>float</td>
+ * <td>{@link RuntimeShader#setFloatUniform(String, float)}</td>
+ * </tr>
+ * <tr>
+ * <td>vec2</td>
+ * <td>{@link RuntimeShader#setFloatUniform(String, float, float)}</td>
+ * </tr>
+ * <tr>
+ * <td>vec3</td>
+ * <td>{@link RuntimeShader#setFloatUniform(String, float, float, float)}</td>
+ * </tr>
+ * <tr>
+ * <td>vec4</td>
+ * <td>{@link RuntimeShader#setFloatUniform(String, float, float, float, float)}</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="4">Integers</td>
+ * <td>int</td>
+ * <td>{@link RuntimeShader#setIntUniform(String, int)}</td>
+ * </tr>
+ * <tr>
+ * <td>ivec2</td>
+ * <td>{@link RuntimeShader#setIntUniform(String, int, int)}</td>
+ * </tr>
+ * <tr>
+ * <td>ivec3</td>
+ * <td>{@link RuntimeShader#setIntUniform(String, int, int, int)}</td>
+ * </tr>
+ * <tr>
+ * <td>ivec4</td>
+ * <td>{@link RuntimeShader#setIntUniform(String, int, int, int, int)}</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">Matrices and Arrays</td>
+ * <td>mat2, mat3, and mat4, and float[]</td>
+ * <td>{@link RuntimeShader#setFloatUniform(String, float[])}</td>
+ * </tr>
+ * <tr>
+ * <td>int[]</td>
+ * <td>{@link RuntimeShader#setIntUniform(String, int[])}</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * For example, a simple AGSL shader making use of a float uniform to modulate the transparency
+ * of the output color would look like:</p>
+ *
+ * <pre class="prettyprint">
+ * uniform float alpha;
+ * vec4 main(vec2 canvas_coordinates) {
+ * vec3 red = vec3(1.0, 0.0, 0.0);
+ * return vec4(red * alpha, alpha);
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the uniform can then be initialized
+ * and updated per frame by calling {@link RuntimeShader#setFloatUniform(String, float)} with the
+ * value of alpha. The value of a primitive uniform defaults to 0 if it is declared in the AGSL
+ * shader but not initialized.</p>
+ *
+ * <h4>Color Uniforms</h4>
+ * <p>AGSL doesn't know if uniform variables contain colors, it won't automatically convert them to
+ * the working colorspace of the shader at runtime. However, you can label your vec4 uniform with
+ * the "layout(color)" qualifier which lets Android know that the uniform will be used as a color.
+ * Doing so allows AGSL to transform the uniform value to the working color space. In AGSL, declare
+ * the uniform like this:
+ *
+ * <pre class="prettyprint">
+ * layout(color) uniform vec4 inputColorA;
+ * layout(color) uniform vec4 inputColorB;
+ * vec4 main(vec2 canvas_coordinates) {
+ * // blend the two colors together and return the resulting color
+ * return mix(inputColorA, inputColorB, 0.5);
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the uniforms can
+ * then be initialized and updated per frame by calling
+ * {@link RuntimeShader#setColorUniform(String, int)},
+ * {@link RuntimeShader#setColorUniform(String, long)}, or
+ * {@link RuntimeShader#setColorUniform(String, Color)} with the desired colors. The value of a
+ * color uniform is undefined if it is declared in the AGSL shader but not initialized.</p>
+ *
+ * <h4>Shader Uniforms</h4>
+ * In GLSL, a fragment shader can sample a texture. For AGSL instead of sampling textures you can
+ * sample from any {@link Shader}, which includes but is not limited to {@link BitmapShader}. To
+ * make it clear that you are operating on an {@link Shader} object there is no "sample"
+ * method. Instead, the shader uniform has an "eval()" method. This distinction enables AGSL shaders
+ * to sample from existing bitmap and gradient shaders as well as other {@link RuntimeShader}
+ * objects. In AGSL, declare the uniform like this:
+ *
+ * <pre class="prettyprint">
+ * uniform shader myShader;
+ * vec4 main(vec2 canvas_coordinates) {
+ * // swap the red and blue color channels when sampling from myShader
+ * return myShader.sample(canvas_coordinates).bgra;
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the shader uniform can
+ * then be initialized and updated per frame by calling
+ * {@link RuntimeShader#setInputShader(String, Shader)} with the desired shader. The value of a
+ * shader uniform is undefined if it is declared in the AGSL shader but not initialized.</p>
+ *
+ * <p>Although most {@link BitmapShader}s contain colors that should be color managed, some contain
+ * data that isn’t actually colors. This includes bitmaps storing normals, material properties
+ * (e.g. roughness), heightmaps, or any other purely mathematical data that happens to be stored in
+ * a bitmap. When using these kinds of shaders in AGSL, you probably want to initialize them with
+ * {@link #setInputBuffer(String, BitmapShader)}. Shaders initialized this way work much like
+ * a regular {@link BitmapShader} (including filtering and tiling), with a few major differences:
+ * <ul>
+ * <li>No color space transformation is applied (the color space of the bitmap is ignored).</li>
+ * <li>Bitmaps that return false for {@link Bitmap#isPremultiplied()} are not automatically
+ * premultiplied.</li>
+ * </ul>
+ *
+ * <p>In addition, when sampling from a {@link BitmapShader} be aware that the shader does not use
+ * normalized coordinates (like a texture in GLSL). It uses (0, 0) in the upper-left corner, and
+ * (width, height) in the bottom-right corner. Normally, this is exactly what you want. If you’re
+ * evaluating the shader with coordinates based on the ones passed to your AGSL program, the scale
+ * is correct. However, if you want to adjust those coordinates (to do some kind of re-mapping of
+ * the bitmap), remember that the coordinates are local to the canvas.</p>
+ *
*/
public class RuntimeShader extends Shader {
diff --git a/identity/java/android/security/identity/CredentialDataRequest.java b/identity/java/android/security/identity/CredentialDataRequest.java
index 2a47a02405e0..3482384a1fd9 100644
--- a/identity/java/android/security/identity/CredentialDataRequest.java
+++ b/identity/java/android/security/identity/CredentialDataRequest.java
@@ -153,7 +153,15 @@ public class CredentialDataRequest {
/**
* Sets whether to allow using an authentication key which use count has been exceeded.
*
- * By default this is set to true.
+ * <p>This is useful in situations where the application hasn't had a chance to renew
+ * authentication keys, for example if the device hasn't been connected to the Internet or
+ * if the issuing authority server has been down.
+ *
+ * <p>The reason this could be useful is that the privacy risk of reusing an authentication
+ * key for a credential presentation could be significantly smaller compared to the
+ * inconvenience of not being able to present the credential at all.
+ *
+ * <p>By default this is set to true.
*
* @param allowUsingExhaustedKeys whether to allow using an authentication key which use
* count has been exceeded if no other key is available.
@@ -167,7 +175,16 @@ public class CredentialDataRequest {
/**
* Sets whether to allow using an authentication key which is expired.
*
- * By default this is set to false.
+ * <p>This is useful in situations where the application hasn't had a chance to renew
+ * authentication keys, for example if the device hasn't been connected to the Internet or
+ * if the issuing authority server has been down.
+ *
+ * <p>The reason this could be useful is that many verifiers are likely to accept a
+ * credential presentation using an expired authentication key (the credential itself
+ * wouldn't be expired) and it's likely better for the holder to be able to do this than
+ * not present their credential at all.
+ *
+ * <p>By default this is set to false.
*
* @param allowUsingExpiredKeys whether to allow using an authentication key which is
* expired if no other key is available.
@@ -181,7 +198,12 @@ public class CredentialDataRequest {
/**
* Sets whether to increment the use-count for the authentication key used.
*
- * By default this is set to true.
+ * <p>Not incrementing the use-count for an authentication key is useful in situations
+ * where the authentication key is known with certainty to not be leaked. For example,
+ * consider an application doing a credential presentation for the sole purpose of
+ * displaying the credential data to the user (not for verification).
+ *
+ * <p>By default this is set to true.
*
* @param incrementUseCount whether to increment the use count of the authentication
* key used.
diff --git a/identity/java/android/security/identity/PresentationSession.java b/identity/java/android/security/identity/PresentationSession.java
index afaafce32798..6cde611fcd63 100644
--- a/identity/java/android/security/identity/PresentationSession.java
+++ b/identity/java/android/security/identity/PresentationSession.java
@@ -26,6 +26,9 @@ import java.security.PublicKey;
/**
* Class for presenting multiple documents to a remote verifier.
*
+ * <p>This should be used for all interactions with a remote verifier instead of the now deprecated
+ * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} method.
+ *
* Use {@link IdentityCredentialStore#createPresentationSession(int)} to create a {@link
* PresentationSession} instance.
*/
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 358104fffbf6..e5d127609b2e 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -83,16 +83,10 @@ public class AndroidKeyStoreProvider extends Provider {
// java.security.KeyPairGenerator
put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC");
put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
- put("KeyPairGenerator." + X25519_ALIAS,
- PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
- put("KeyPairGenerator." + ED25519_OID,
- PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
// java.security.KeyFactory
putKeyFactoryImpl("EC");
putKeyFactoryImpl("RSA");
- putKeyFactoryImpl(X25519_ALIAS);
- putKeyFactoryImpl(ED25519_OID);
// javax.crypto.KeyGenerator
put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES");
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index eb9429747b66..1c49881904e4 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -18,17 +18,73 @@ package androidx.window.common;
import static androidx.window.util.ExtensionHelper.isZero;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
+import android.util.Log;
import androidx.annotation.NonNull;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-final class CommonDisplayFeature implements DisplayFeature {
+/** A representation of a folding feature for both Extension and Sidecar.
+ * For Sidecar this is the same as combining {@link androidx.window.sidecar.SidecarDeviceState} and
+ * {@link androidx.window.sidecar.SidecarDisplayFeature}. For Extensions this is the mirror of
+ * {@link androidx.window.extensions.layout.FoldingFeature}.
+ */
+public final class CommonFoldingFeature {
+
+ private static final boolean DEBUG = false;
+
+ public static final String TAG = CommonFoldingFeature.class.getSimpleName();
+
+ /**
+ * A common type to represent a hinge where the screen is continuous.
+ */
+ public static final int COMMON_TYPE_FOLD = 1;
+
+ /**
+ * A common type to represent a hinge where there is a physical gap separating multiple
+ * displays.
+ */
+ public static final int COMMON_TYPE_HINGE = 2;
+
+ @IntDef({COMMON_TYPE_FOLD, COMMON_TYPE_HINGE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {
+ }
+
+ /**
+ * A common state to represent when the state is not known. One example is if the device is
+ * closed. We do not emit this value for developers but is useful for implementation reasons.
+ */
+ public static final int COMMON_STATE_UNKNOWN = -1;
+
+ /**
+ * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
+ * and Extensions do not match exactly.
+ */
+ public static final int COMMON_STATE_FLAT = 3;
+ /**
+ * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
+ * Sidecar and Extensions do not match exactly.
+ */
+ public static final int COMMON_STATE_HALF_OPENED = 2;
+
+ /**
+ * The possible states for a folding hinge.
+ */
+ @IntDef({COMMON_STATE_UNKNOWN, COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface State {
+ }
+
private static final Pattern FEATURE_PATTERN =
Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]-?(flat|half-opened)?");
@@ -38,17 +94,49 @@ final class CommonDisplayFeature implements DisplayFeature {
private static final String PATTERN_STATE_FLAT = "flat";
private static final String PATTERN_STATE_HALF_OPENED = "half-opened";
- // TODO(b/183049815): Support feature strings that include the state of the feature.
+ /**
+ * Parse a {@link List} of {@link CommonFoldingFeature} from a {@link String}.
+ * @param value a {@link String} representation of multiple {@link CommonFoldingFeature}
+ * separated by a ":".
+ * @param hingeState a global fallback value for a {@link CommonFoldingFeature} if one is not
+ * specified in the input.
+ * @throws IllegalArgumentException if the provided string is improperly formatted or could not
+ * otherwise be parsed.
+ * @see #FEATURE_PATTERN
+ * @return {@link List} of {@link CommonFoldingFeature}.
+ */
+ static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
+ @State int hingeState) {
+ List<CommonFoldingFeature> features = new ArrayList<>();
+ String[] featureStrings = value.split(";");
+ for (String featureString : featureStrings) {
+ CommonFoldingFeature feature;
+ try {
+ feature = CommonFoldingFeature.parseFromString(featureString, hingeState);
+ } catch (IllegalArgumentException e) {
+ if (DEBUG) {
+ Log.w(TAG, "Failed to parse display feature: " + featureString, e);
+ }
+ continue;
+ }
+ features.add(feature);
+ }
+ return features;
+ }
/**
* Parses a display feature from a string.
*
+ * @param string A {@link String} representation of a {@link CommonFoldingFeature}.
+ * @param hingeState A fallback value for the {@link State} if it is not specified in the input.
* @throws IllegalArgumentException if the provided string is improperly formatted or could not
* otherwise be parsed.
+ * @return {@link CommonFoldingFeature} represented by the {@link String} value.
* @see #FEATURE_PATTERN
*/
@NonNull
- static CommonDisplayFeature parseFromString(@NonNull String string) {
+ private static CommonFoldingFeature parseFromString(@NonNull String string,
+ @State int hingeState) {
Matcher featureMatcher = FEATURE_PATTERN.matcher(string);
if (!featureMatcher.matches()) {
throw new IllegalArgumentException("Malformed feature description format: " + string);
@@ -59,10 +147,10 @@ final class CommonDisplayFeature implements DisplayFeature {
int type;
switch (featureType) {
case FEATURE_TYPE_FOLD:
- type = 1 /* TYPE_FOLD */;
+ type = COMMON_TYPE_FOLD;
break;
case FEATURE_TYPE_HINGE:
- type = 2 /* TYPE_HINGE */;
+ type = COMMON_TYPE_HINGE;
break;
default: {
throw new IllegalArgumentException("Malformed feature type: " + featureType);
@@ -79,7 +167,7 @@ final class CommonDisplayFeature implements DisplayFeature {
}
String stateString = featureMatcher.group(6);
stateString = stateString == null ? "" : stateString;
- Integer state;
+ final int state;
switch (stateString) {
case PATTERN_STATE_FLAT:
state = COMMON_STATE_FLAT;
@@ -88,10 +176,10 @@ final class CommonDisplayFeature implements DisplayFeature {
state = COMMON_STATE_HALF_OPENED;
break;
default:
- state = null;
+ state = hingeState;
break;
}
- return new CommonDisplayFeature(type, state, featureRect);
+ return new CommonFoldingFeature(type, state, featureRect);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Malformed feature description: " + string, e);
}
@@ -99,11 +187,11 @@ final class CommonDisplayFeature implements DisplayFeature {
private final int mType;
@Nullable
- private final Integer mState;
+ private final int mState;
@NonNull
private final Rect mRect;
- CommonDisplayFeature(int type, @Nullable Integer state, @NonNull Rect rect) {
+ CommonFoldingFeature(int type, int state, @NonNull Rect rect) {
assertValidState(state);
this.mType = type;
this.mState = state;
@@ -114,16 +202,19 @@ final class CommonDisplayFeature implements DisplayFeature {
this.mRect = rect;
}
+ /** Returns the type of the feature. */
+ @Type
public int getType() {
return mType;
}
- /** Returns the state of the feature, or {@code null} if the feature has no state. */
- @Nullable
- public Integer getState() {
+ /** Returns the state of the feature.*/
+ @State
+ public int getState() {
return mState;
}
+ /** Returns the bounds of the feature. */
@NonNull
public Rect getRect() {
return mRect;
@@ -133,7 +224,7 @@ final class CommonDisplayFeature implements DisplayFeature {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- CommonDisplayFeature that = (CommonDisplayFeature) o;
+ CommonFoldingFeature that = (CommonFoldingFeature) o;
return mType == that.mType
&& Objects.equals(mState, that.mState)
&& mRect.equals(that.mRect);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index fa9a5a8b7a1b..6987401525b4 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -18,11 +18,15 @@ package androidx.window.common;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
@@ -30,6 +34,7 @@ import androidx.window.util.BaseDataProducer;
import com.android.internal.R;
+import java.util.List;
import java.util.Optional;
/**
@@ -37,10 +42,13 @@ import java.util.Optional;
* by mapping the state returned from {@link DeviceStateManager} to values provided in the resources
* config at {@link R.array#config_device_state_postures}.
*/
-public final class DeviceStateManagerPostureProducer extends BaseDataProducer<Integer> {
- private static final String TAG = "ConfigDevicePostureProducer";
+public final class DeviceStateManagerFoldingFeatureProducer extends
+ BaseDataProducer<List<CommonFoldingFeature>> {
+ private static final String TAG =
+ DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
private static final boolean DEBUG = false;
+ private final Context mContext;
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
private int mCurrentDeviceState = INVALID_DEVICE_STATE;
@@ -50,7 +58,8 @@ public final class DeviceStateManagerPostureProducer extends BaseDataProducer<In
notifyDataChanged();
};
- public DeviceStateManagerPostureProducer(@NonNull Context context) {
+ public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
+ mContext = context;
String[] deviceStatePosturePairs = context.getResources()
.getStringArray(R.array.config_device_state_postures);
for (String deviceStatePosturePair : deviceStatePosturePairs) {
@@ -86,8 +95,17 @@ public final class DeviceStateManagerPostureProducer extends BaseDataProducer<In
@Override
@Nullable
- public Optional<Integer> getData() {
- final int posture = mDeviceStateToPostureMap.get(mCurrentDeviceState, -1);
- return posture != -1 ? Optional.of(posture) : Optional.empty();
+ public Optional<List<CommonFoldingFeature>> getData() {
+ final int globalHingeState = globalHingeState();
+ String displayFeaturesString = mContext.getResources().getString(
+ R.string.config_display_features);
+ if (TextUtils.isEmpty(displayFeaturesString)) {
+ return Optional.empty();
+ }
+ return Optional.of(parseListFromString(displayFeaturesString, globalHingeState));
+ }
+
+ private int globalHingeState() {
+ return mDeviceStateToPostureMap.get(mCurrentDeviceState, COMMON_STATE_UNKNOWN);
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
deleted file mode 100644
index 573641857b99..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-public interface DisplayFeature {
- /** Returns the type of the feature. */
- int getType();
-
- /** Returns the state of the feature, or {@code null} if the feature has no state. */
- @Nullable
- @State
- Integer getState();
-
- /** Returns the bounds of the feature. */
- @NonNull
- Rect getRect();
-
- /**
- * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
- * and Extensions do not match exactly.
- */
- int COMMON_STATE_FLAT = 3;
- /**
- * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
- * Sidecar and Extensions do not match exactly.
- */
- int COMMON_STATE_HALF_OPENED = 2;
-
- /**
- * The possible states for a folding hinge.
- */
- @IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
- @Retention(RetentionPolicy.SOURCE)
- @interface State {}
-
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
new file mode 100644
index 000000000000..d923a46c3b5d
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.common;
+
+import android.app.Activity;
+import android.app.Application;
+import android.os.Bundle;
+
+/**
+ * An empty implementation of {@link Application.ActivityLifecycleCallbacks} derived classes can
+ * implement the methods necessary.
+ */
+public class EmptyLifecycleCallbacksAdapter implements Application.ActivityLifecycleCallbacks {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
deleted file mode 100644
index cd2cadc082e1..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.window.util.BaseDataProducer;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in the resources config at
- * {@link R.string#config_display_features}.
- */
-public final class ResourceConfigDisplayFeatureProducer extends
- BaseDataProducer<List<DisplayFeature>> {
- private static final boolean DEBUG = false;
- private static final String TAG = "ResourceConfigDisplayFeatureProducer";
-
- private final Context mContext;
-
- public ResourceConfigDisplayFeatureProducer(@NonNull Context context) {
- mContext = context;
- }
-
- @Override
- @Nullable
- public Optional<List<DisplayFeature>> getData() {
- String displayFeaturesString = mContext.getResources().getString(
- R.string.config_display_features);
- if (TextUtils.isEmpty(displayFeaturesString)) {
- return Optional.empty();
- }
-
- List<DisplayFeature> features = new ArrayList<>();
- String[] featureStrings = displayFeaturesString.split(";");
- for (String featureString : featureStrings) {
- CommonDisplayFeature feature;
- try {
- feature = CommonDisplayFeature.parseFromString(featureString);
- } catch (IllegalArgumentException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to parse display feature: " + featureString, e);
- }
- continue;
- }
- features.add(feature);
- }
- return Optional.of(features);
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
deleted file mode 100644
index 2026df3fa979..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-
-import androidx.window.util.BaseDataProducer;
-
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that provides the device posture
- * as an {@link Integer} from a value stored in {@link Settings}.
- */
-public final class SettingsDevicePostureProducer extends BaseDataProducer<Integer> {
- private static final String DEVICE_POSTURE = "device_posture";
-
- private final Uri mDevicePostureUri =
- Settings.Global.getUriFor(DEVICE_POSTURE);
-
- private final ContentResolver mResolver;
- private final ContentObserver mObserver;
- private boolean mRegisteredObservers;
-
- public SettingsDevicePostureProducer(@NonNull Context context) {
- mResolver = context.getContentResolver();
- mObserver = new SettingsObserver();
- }
-
- @Override
- @Nullable
- public Optional<Integer> getData() {
- int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, -1);
- return posture == -1 ? Optional.empty() : Optional.of(posture);
- }
-
- /**
- * Registers settings observers, if needed. When settings observers are registered for this
- * producer callbacks for changes in data will be triggered.
- */
- public void registerObserversIfNeeded() {
- if (mRegisteredObservers) {
- return;
- }
- mRegisteredObservers = true;
- mResolver.registerContentObserver(mDevicePostureUri, false /* notifyForDescendants */,
- mObserver /* ContentObserver */);
- }
-
- /**
- * Unregisters settings observers, if needed. When settings observers are unregistered for this
- * producer callbacks for changes in data will not be triggered.
- */
- public void unregisterObserversIfNeeded() {
- if (!mRegisteredObservers) {
- return;
- }
- mRegisteredObservers = false;
- mResolver.unregisterContentObserver(mObserver);
- }
-
- private final class SettingsObserver extends ContentObserver {
- SettingsObserver() {
- super(new Handler(Looper.getMainLooper()));
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (mDevicePostureUri.equals(uri)) {
- notifyDataChanged();
- }
- }
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
index 040662657a74..e9d213e06fa9 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
@@ -16,8 +16,10 @@
package androidx.window.common;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -26,22 +28,19 @@ import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.Log;
import androidx.window.util.BaseDataProducer;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in {@link Settings}.
+ * {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
*/
public final class SettingsDisplayFeatureProducer
- extends BaseDataProducer<List<DisplayFeature>> {
- private static final boolean DEBUG = false;
- private static final String TAG = "SettingsDisplayFeatureProducer";
+ extends BaseDataProducer<List<CommonFoldingFeature>> {
private static final String DISPLAY_FEATURES = "display_features";
private final Uri mDisplayFeaturesUri =
@@ -57,32 +56,17 @@ public final class SettingsDisplayFeatureProducer
}
@Override
- @Nullable
- public Optional<List<DisplayFeature>> getData() {
+ @NonNull
+ public Optional<List<CommonFoldingFeature>> getData() {
String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
if (displayFeaturesString == null) {
return Optional.empty();
}
- List<DisplayFeature> features = new ArrayList<>();
if (TextUtils.isEmpty(displayFeaturesString)) {
- return Optional.of(features);
- }
- String[] featureStrings = displayFeaturesString.split(";");
-
- for (String featureString : featureStrings) {
- CommonDisplayFeature feature;
- try {
- feature = CommonDisplayFeature.parseFromString(featureString);
- } catch (IllegalArgumentException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to parse display feature: " + featureString, e);
- }
- continue;
- }
- features.add(feature);
+ return Optional.of(Collections.emptyList());
}
- return Optional.of(features);
+ return Optional.of(parseListFromString(displayFeaturesString, COMMON_STATE_UNKNOWN));
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 6d8383372461..1d2b9384f47d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -28,7 +28,6 @@ import android.app.Activity;
import android.app.ActivityClient;
import android.app.ActivityOptions;
import android.app.ActivityThread;
-import android.app.Application.ActivityLifecycleCallbacks;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
@@ -41,6 +40,8 @@ import android.os.Looper;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -763,11 +764,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return shouldRetainAssociatedContainer(finishingContainer, associatedContainer);
}
- private final class LifecycleCallbacks implements ActivityLifecycleCallbacks {
-
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
- }
+ private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
@Override
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
@@ -779,30 +776,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
@Override
- public void onActivityStarted(Activity activity) {
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- }
-
- @Override
public void onActivityConfigurationChanged(Activity activity) {
SplitController.this.onActivityConfigurationChanged(activity);
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index fe9ce971d4d9..a4fbdbc493f5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -18,28 +18,30 @@ package androidx.window.extensions.layout;
import static android.view.Display.DEFAULT_DISPLAY;
-import static androidx.window.common.DisplayFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.DisplayFeature.COMMON_STATE_HALF_OPENED;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
import android.annotation.Nullable;
import android.app.Activity;
+import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.ArrayMap;
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -56,36 +58,27 @@ import java.util.function.Consumer;
*/
public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private static final String TAG = "SampleExtension";
- private static WindowLayoutComponent sInstance;
private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
- new HashMap<>();
-
- private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
- private final DataProducer<Integer> mDevicePostureProducer;
+ new ArrayMap<>();
private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
- private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+ private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
public WindowLayoutComponentImpl(Context context) {
- mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
- mDevicePostureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDevicePostureProducer,
- new DeviceStateManagerPostureProducer(context)
- ));
-
+ ((Application) context.getApplicationContext())
+ .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
+ mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
mSettingsDisplayFeatureProducer,
- new ResourceConfigDisplayFeatureProducer(context)
+ new DeviceStateManagerFoldingFeatureProducer(context)
));
-
- mDevicePostureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+ mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
/**
* Adds a listener interested in receiving updates to {@link WindowLayoutInfo}
+ *
* @param activity hosting a {@link android.view.Window}
* @param consumer interested in receiving updates to {@link WindowLayoutInfo}
*/
@@ -97,6 +90,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
/**
* Removes a listener no longer interested in receiving updates.
+ *
* @param consumer no longer interested in receiving updates to {@link WindowLayoutInfo}
*/
public void removeWindowLayoutInfoListener(
@@ -118,43 +112,34 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return mWindowLayoutChangeListeners.keySet();
}
- protected boolean hasListeners() {
- return !mWindowLayoutChangeListeners.isEmpty();
+ @NonNull
+ private boolean isListeningForLayoutChanges(IBinder token) {
+ for (Activity activity: getActivitiesListeningForLayoutChanges()) {
+ if (token.equals(activity.getWindow().getAttributes().token)) {
+ return true;
+ }
+ }
+ return false;
}
- /**
- * Calculate the {@link DisplayFeature.State} from the feature or the device posture producer.
- * If the given {@link DisplayFeature.State} is not valid then {@code null} will be returned.
- * The {@link FoldingFeature} should be ignored in the case of an invalid
- * {@link DisplayFeature.State}.
- *
- * @param feature a {@link DisplayFeature} to provide the feature state if present.
- * @return {@link DisplayFeature.State} of the hinge if present or the state from the posture
- * produce if present.
- */
- @Nullable
- private Integer getFeatureState(DisplayFeature feature) {
- Integer featureState = feature.getState();
- Optional<Integer> posture = mDevicePostureProducer.getData();
- Integer state = featureState == null ? posture.orElse(null) : featureState;
- return convertToExtensionState(state);
+ protected boolean hasListeners() {
+ return !mWindowLayoutChangeListeners.isEmpty();
}
/**
* A convenience method to translate from the common feature state to the extensions feature
- * state. More specifically, translates from {@link DisplayFeature.State} to
+ * state. More specifically, translates from {@link CommonFoldingFeature.State} to
* {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED}. If it is not
* possible to translate, then we will return a {@code null} value.
*
- * @param state if it matches a value in {@link DisplayFeature.State}, {@code null} otherwise.
- * @return a {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED} if
- * the given state matches a value in {@link DisplayFeature.State} and {@code null} otherwise.
+ * @param state if it matches a value in {@link CommonFoldingFeature.State}, {@code null}
+ * otherwise. @return a {@link FoldingFeature.STATE_FLAT} or
+ * {@link FoldingFeature.STATE_HALF_OPENED} if the given state matches a value in
+ * {@link CommonFoldingFeature.State} and {@code null} otherwise.
*/
@Nullable
- private Integer convertToExtensionState(@Nullable Integer state) {
- if (state == null) { // The null check avoids a NullPointerException.
- return null;
- } else if (state == COMMON_STATE_FLAT) {
+ private Integer convertToExtensionState(int state) {
+ if (state == COMMON_STATE_FLAT) {
return FoldingFeature.STATE_FLAT;
} else if (state == COMMON_STATE_HALF_OPENED) {
return FoldingFeature.STATE_HALF_OPENED;
@@ -172,33 +157,30 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
@NonNull
private WindowLayoutInfo getWindowLayoutInfo(@NonNull Activity activity) {
- List<androidx.window.extensions.layout.DisplayFeature> displayFeatures =
- getDisplayFeatures(activity);
+ List<DisplayFeature> displayFeatures = getDisplayFeatures(activity);
return new WindowLayoutInfo(displayFeatures);
}
/**
- * Translate from the {@link DisplayFeature} to
- * {@link androidx.window.extensions.layout.DisplayFeature} for a given {@link Activity}. If a
- * {@link DisplayFeature} is not valid then it will be omitted.
+ * Translate from the {@link CommonFoldingFeature} to
+ * {@link DisplayFeature} for a given {@link Activity}. If a
+ * {@link CommonFoldingFeature} is not valid then it will be omitted.
*
* For a {@link FoldingFeature} the bounds are localized into the {@link Activity} window
- * coordinate space and the state is calculated either from {@link DisplayFeature#getState()} or
- * {@link #mDisplayFeatureProducer}. The state from {@link #mDisplayFeatureProducer} may not be
- * valid since {@link #mDisplayFeatureProducer} is a general state controller. If the state is
- * not valid, the {@link FoldingFeature} is omitted from the {@link List} of
- * {@link androidx.window.extensions.layout.DisplayFeature}. If the bounds are not valid,
- * constructing a {@link FoldingFeature} will throw an {@link IllegalArgumentException} since
- * this can cause negative UI effects down stream.
+ * coordinate space and the state is calculated from {@link CommonFoldingFeature#getState()}.
+ * The state from {@link #mFoldingFeatureProducer} may not be valid since
+ * {@link #mFoldingFeatureProducer} is a general state controller. If the state is not valid,
+ * the {@link FoldingFeature} is omitted from the {@link List} of {@link DisplayFeature}. If the
+ * bounds are not valid, constructing a {@link FoldingFeature} will throw an
+ * {@link IllegalArgumentException} since this can cause negative UI effects down stream.
*
* @param activity a proxy for the {@link android.view.Window} that contains the
- * {@link androidx.window.extensions.layout.DisplayFeature}.
- * @return a {@link List} of valid {@link androidx.window.extensions.layout.DisplayFeature} that
+ * {@link DisplayFeature}.
+ * @return a {@link List} of valid {@link DisplayFeature} that
* are within the {@link android.view.Window} of the {@link Activity}
*/
- private List<androidx.window.extensions.layout.DisplayFeature> getDisplayFeatures(
- @NonNull Activity activity) {
- List<androidx.window.extensions.layout.DisplayFeature> features = new ArrayList<>();
+ private List<DisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
+ List<DisplayFeature> features = new ArrayList<>();
int displayId = activity.getDisplay().getDisplayId();
if (displayId != DEFAULT_DISPLAY) {
Log.w(TAG, "This sample doesn't support display features on secondary displays");
@@ -211,11 +193,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return features;
}
- Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+ Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
if (storedFeatures.isPresent()) {
-
- for (DisplayFeature baseFeature : storedFeatures.get()) {
- Integer state = getFeatureState(baseFeature);
+ for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
+ Integer state = convertToExtensionState(baseFeature.getState());
if (state == null) {
continue;
}
@@ -223,8 +204,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
rotateRectToDisplayRotation(displayId, featureRect);
transformToWindowSpaceRect(activity, featureRect);
- features.add(new FoldingFeature(featureRect, baseFeature.getType(),
- getFeatureState(baseFeature)));
+ features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
}
}
return features;
@@ -232,13 +212,31 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private void updateRegistrations() {
if (hasListeners()) {
- mSettingsDevicePostureProducer.registerObserversIfNeeded();
mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
} else {
- mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
}
-
onDisplayFeaturesChanged();
}
+
+ private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ super.onActivityCreated(activity, savedInstanceState);
+ onDisplayFeaturesChangedIfListening(activity);
+ }
+
+ @Override
+ public void onActivityConfigurationChanged(Activity activity) {
+ super.onActivityConfigurationChanged(activity);
+ onDisplayFeaturesChangedIfListening(activity);
+ }
+
+ private void onDisplayFeaturesChangedIfListening(Activity activity) {
+ IBinder token = activity.getWindow().getAttributes().token;
+ if (token == null || isListeningForLayoutChanges(token)) {
+ onDisplayFeaturesChanged();
+ }
+ }
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index aa949f126154..c7b709347060 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -23,16 +23,17 @@ import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
import android.app.Activity;
import android.app.ActivityThread;
+import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;
@@ -48,36 +49,25 @@ import java.util.Optional;
*/
class SampleSidecarImpl extends StubSidecar {
private static final String TAG = "SampleSidecar";
- private static final boolean DEBUG = false;
- private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
- private final DataProducer<Integer> mDevicePostureProducer;
+ private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
- private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
- private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+ private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
SampleSidecarImpl(Context context) {
- mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
- mDevicePostureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDevicePostureProducer,
- new DeviceStateManagerPostureProducer(context)
+ ((Application) context.getApplicationContext())
+ .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
+ mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
+ mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
+ mSettingsFoldingFeatureProducer,
+ new DeviceStateManagerFoldingFeatureProducer(context)
));
- mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDisplayFeatureProducer,
- new ResourceConfigDisplayFeatureProducer(context)
- ));
-
- mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged);
- mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- }
-
- private void onDevicePostureChanged() {
- updateDeviceState(getDeviceState());
+ mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
private void onDisplayFeaturesChanged() {
+ updateDeviceState(getDeviceState());
for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
updateWindowLayout(windowToken, newLayout);
@@ -87,27 +77,21 @@ class SampleSidecarImpl extends StubSidecar {
@NonNull
@Override
public SidecarDeviceState getDeviceState() {
- Optional<Integer> posture = mDevicePostureProducer.getData();
-
SidecarDeviceState deviceState = new SidecarDeviceState();
- deviceState.posture = posture.orElse(deviceStateFromFeature());
+ deviceState.posture = deviceStateFromFeature();
return deviceState;
}
private int deviceStateFromFeature() {
- List<DisplayFeature> storedFeatures = mDisplayFeatureProducer.getData()
+ List<CommonFoldingFeature> storedFeatures = mFoldingFeatureProducer.getData()
.orElse(Collections.emptyList());
for (int i = 0; i < storedFeatures.size(); i++) {
- DisplayFeature feature = storedFeatures.get(i);
- final int state = feature.getState() == null ? -1 : feature.getState();
- if (DEBUG && feature.getState() == null) {
- Log.d(TAG, "feature#getState was null for DisplayFeature: " + feature);
- }
-
+ CommonFoldingFeature feature = storedFeatures.get(i);
+ final int state = feature.getState();
switch (state) {
- case DisplayFeature.COMMON_STATE_FLAT:
+ case CommonFoldingFeature.COMMON_STATE_FLAT:
return SidecarDeviceState.POSTURE_OPENED;
- case DisplayFeature.COMMON_STATE_HALF_OPENED:
+ case CommonFoldingFeature.COMMON_STATE_HALF_OPENED:
return SidecarDeviceState.POSTURE_HALF_OPENED;
}
}
@@ -127,22 +111,22 @@ class SampleSidecarImpl extends StubSidecar {
}
private List<SidecarDisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
- List<SidecarDisplayFeature> features = new ArrayList<SidecarDisplayFeature>();
int displayId = activity.getDisplay().getDisplayId();
if (displayId != DEFAULT_DISPLAY) {
Log.w(TAG, "This sample doesn't support display features on secondary displays");
- return features;
+ return Collections.emptyList();
}
if (activity.isInMultiWindowMode()) {
// It is recommended not to report any display features in multi-window mode, since it
// won't be possible to synchronize the display feature positions with window movement.
- return features;
+ return Collections.emptyList();
}
- Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+ Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
+ List<SidecarDisplayFeature> features = new ArrayList<>();
if (storedFeatures.isPresent()) {
- for (DisplayFeature baseFeature : storedFeatures.get()) {
+ for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
SidecarDisplayFeature feature = new SidecarDisplayFeature();
Rect featureRect = baseFeature.getRect();
rotateRectToDisplayRotation(displayId, featureRect);
@@ -152,17 +136,37 @@ class SampleSidecarImpl extends StubSidecar {
features.add(feature);
}
}
- return features;
+ return Collections.unmodifiableList(features);
}
@Override
protected void onListenersChanged() {
if (hasListeners()) {
- mSettingsDevicePostureProducer.registerObserversIfNeeded();
- mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
+ mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
+ onDisplayFeaturesChanged();
} else {
- mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
- mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
+ mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
+ }
+ }
+
+ private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ super.onActivityCreated(activity, savedInstanceState);
+ onDisplayFeaturesChangedForActivity(activity);
+ }
+
+ @Override
+ public void onActivityConfigurationChanged(Activity activity) {
+ super.onActivityConfigurationChanged(activity);
+ onDisplayFeaturesChangedForActivity(activity);
+ }
+
+ private void onDisplayFeaturesChangedForActivity(@NonNull Activity activity) {
+ IBinder token = activity.getWindow().getAttributes().token;
+ if (token == null || mWindowLayoutChangeListenerTokens.contains(token)) {
+ onDisplayFeaturesChanged();
+ }
}
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
index 199c37315c07..b9c808a6569b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
@@ -30,7 +30,7 @@ import java.util.Set;
abstract class StubSidecar implements SidecarInterface {
private SidecarCallback mSidecarCallback;
- private final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
+ final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
private boolean mDeviceStateChangeListenerRegistered;
StubSidecar() {
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
index cd9c26065dc1..43cba1a37bc8 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ 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.
@@ -14,10 +14,6 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/communal_host"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/> \ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_neutral1_900" android:alpha="0.6" />
+</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
index 0d8a8faa9798..42572d64b96f 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
@@ -15,6 +15,6 @@
~ limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@android:color/system_accent1_10">
+ android:color="@color/letterbox_education_dismiss_button_background_ripple">
<item android:drawable="@drawable/letterbox_education_dismiss_button_background"/>
</ripple> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 91ea436f81b6..3f8343a7abd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -98,16 +98,22 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
default void onTaskInfoChanged(RunningTaskInfo taskInfo) {}
default void onTaskVanished(RunningTaskInfo taskInfo) {}
default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {}
- /** Whether this task listener supports compat UI. */
+ /** Whether this task listener supports compat UI. */
default boolean supportCompatUI() {
// All TaskListeners should support compat UI except PIP.
return true;
}
- /** Attaches the a child window surface to the task surface. */
+ /** Attaches a child window surface to the task surface. */
default void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
throw new IllegalStateException(
"This task listener doesn't support child surface attachment.");
}
+ /** Reparents a child window surface to the task surface. */
+ default void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ throw new IllegalStateException(
+ "This task listener doesn't support child surface reparent.");
+ }
default void dump(@NonNull PrintWriter pw, String prefix) {};
}
@@ -620,6 +626,23 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
updateCameraCompatControlState(info.getTaskInfo().token, state);
}
+ /** Reparents a child window surface to the task surface. */
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ final TaskListener taskListener;
+ synchronized (mLock) {
+ taskListener = mTasks.contains(taskId)
+ ? getTaskListener(mTasks.get(taskId).getTaskInfo())
+ : null;
+ }
+ if (taskListener == null) {
+ ProtoLog.w(WM_SHELL_TASK_ORG, "Failed to find Task to reparent surface taskId=%d",
+ taskId);
+ return;
+ }
+ taskListener.reparentChildSurfaceToTask(taskId, sc, t);
+ }
+
private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
int event) {
ActivityInfo topActivityInfo = info.getTaskInfo().topActivityInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 54e743f72cc6..ca4ef07eb1db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -367,10 +367,20 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
- if (mTaskInfo.taskId != taskId) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
+ if (mTaskInfo == null || mTaskLeash == null || mTaskInfo.taskId != taskId) {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
- b.setParent(mTaskLeash);
+ return mTaskLeash;
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index e344c3bea42b..33eec335bca3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -275,12 +275,22 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
if (getRootTaskId() == taskId) {
- b.setParent(mRootTaskLeash);
+ return mRootTaskLeash;
} else if (getTaskId1() == taskId) {
- b.setParent(mTaskLeash1);
+ return mTaskLeash1;
} else if (getTaskId2() == taskId) {
- b.setParent(mTaskLeash2);
+ return mTaskLeash2;
} else {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 79e624212f4b..3876533a922e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -173,8 +173,8 @@ public class BadgedImageView extends ConstraintLayout {
}
@Override
- public void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ public void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
if (!shouldDrawDot()) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index 9384e2b4dfdf..d22fb5039052 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.RemoteException;
+import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -36,6 +37,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* This module deals with display rotations coming from WM. When WM starts a rotation: after it has
@@ -245,8 +247,8 @@ public class DisplayController {
}
}
- private void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
- List<Rect> unrestricted) {
+ private void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+ Set<Rect> unrestricted) {
synchronized (mDisplays) {
if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown"
@@ -323,7 +325,8 @@ public class DisplayController {
public void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
List<Rect> unrestricted) {
mMainExecutor.execute(() -> {
- DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted);
+ DisplayController.this.onKeepClearAreasChanged(displayId,
+ new ArraySet<>(restricted), new ArraySet<>(unrestricted));
});
}
}
@@ -364,7 +367,7 @@ public class DisplayController {
/**
* Called when keep-clear areas on a display have changed.
*/
- default void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
- List<Rect> unrestricted) {}
+ default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+ Set<Rect> unrestricted) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
index 99dbfe01964c..b87cf47dd93f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
@@ -24,9 +24,12 @@ import com.android.wm.shell.common.annotations.ExternalThread;
@ExternalThread
public interface CompatUI {
/**
- * Called when the keyguard occluded state changes. Removes all compat UIs if the
- * keyguard is now occluded.
- * @param occluded indicates if the keyguard is now occluded.
+ * Called when the keyguard showing state changes. Removes all compat UIs if the
+ * keyguard is now showing.
+ *
+ * <p>Note that if the keyguard is occluded it will also be considered showing.
+ *
+ * @param showing indicates if the keyguard is now showing.
*/
- void onKeyguardOccludedChanged(boolean occluded);
+ void onKeyguardShowingChanged(boolean showing);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index ee4d5ed018bf..b2bbafeb7bf5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -109,9 +109,9 @@ public class CompatUIController implements OnDisplaysChangedListener,
// Only show each hint once automatically in the process life.
private final CompatUIHintsState mCompatUIHintsState;
- // Indicates if the keyguard is currently occluded, in which case compat UIs shouldn't
+ // Indicates if the keyguard is currently showing, in which case compat UIs shouldn't
// be shown.
- private boolean mKeyguardOccluded;
+ private boolean mKeyguardShowing;
public CompatUIController(Context context,
DisplayController displayController,
@@ -218,14 +218,14 @@ public class CompatUIController implements OnDisplaysChangedListener,
}
@VisibleForTesting
- void onKeyguardOccludedChanged(boolean occluded) {
- mKeyguardOccluded = occluded;
- // Hide the compat UIs when keyguard is occluded.
+ void onKeyguardShowingChanged(boolean showing) {
+ mKeyguardShowing = showing;
+ // Hide the compat UIs when keyguard is showing.
forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
}
private boolean showOnDisplay(int displayId) {
- return !mKeyguardOccluded && !isImeShowingOnDisplay(displayId);
+ return !mKeyguardShowing && !isImeShowingOnDisplay(displayId);
}
private boolean isImeShowingOnDisplay(int displayId) {
@@ -372,9 +372,9 @@ public class CompatUIController implements OnDisplaysChangedListener,
@ExternalThread
private class CompatUIImpl implements CompatUI {
@Override
- public void onKeyguardOccludedChanged(boolean occluded) {
+ public void onKeyguardShowingChanged(boolean showing) {
mMainExecutor.execute(() -> {
- CompatUIController.this.onKeyguardOccludedChanged(occluded);
+ CompatUIController.this.onKeyguardShowingChanged(showing);
});
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
index 2da6a6bc70c0..8aa4d0ee99ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
+import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
@@ -38,6 +39,7 @@ class LetterboxEduDialogLayout extends ConstraintLayout {
// 204 is simply 255 * 0.8.
static final int BACKGROUND_DIM_ALPHA = 204;
private View mDialogContainer;
+ private TextView mDialogTitle;
private Drawable mBackgroundDim;
public LetterboxEduDialogLayout(Context context) {
@@ -61,6 +63,10 @@ class LetterboxEduDialogLayout extends ConstraintLayout {
return mDialogContainer;
}
+ TextView getDialogTitle() {
+ return mDialogTitle;
+ }
+
Drawable getBackgroundDim() {
return mBackgroundDim;
}
@@ -84,6 +90,7 @@ class LetterboxEduDialogLayout extends ConstraintLayout {
protected void onFinishInflate() {
super.onFinishInflate();
mDialogContainer = findViewById(R.id.letterbox_education_dialog_container);
+ mDialogTitle = findViewById(R.id.letterbox_education_dialog_title);
mBackgroundDim = getBackground().mutate();
// Set the alpha of the background dim to 0 for enter animation.
mBackgroundDim.setAlpha(0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
index 30b9f0838e10..dda72ffb432f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
@@ -28,6 +28,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
@@ -132,7 +133,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
updateDialogMargins();
mAnimationController.startEnterAnimation(mLayout, /* endCallback= */
- this::setDismissOnClickListener);
+ this::onDialogEnterAnimationEnded);
return mLayout;
}
@@ -157,11 +158,13 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
R.layout.letterbox_education_dialog_layout, null);
}
- private void setDismissOnClickListener() {
+ private void onDialogEnterAnimationEnded() {
if (mLayout == null) {
return;
}
mLayout.setDismissOnClickListener(this::onDismiss);
+ // Focus on the dialog title for accessibility.
+ mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
private void onDismiss() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
index 4f160427dca6..1e934c5c6e22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
@@ -27,7 +27,6 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.annotations.ShellMainThread;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipMediaController;
@@ -68,6 +67,7 @@ public abstract class TvPipModule {
PipTransitionController pipTransitionController,
TvPipNotificationController tvPipNotificationController,
TaskStackListenerImpl taskStackListener,
+ DisplayController displayController,
WindowManagerShellWrapper windowManagerShellWrapper,
@ShellMainThread ShellExecutor mainExecutor) {
return Optional.of(
@@ -81,6 +81,7 @@ public abstract class TvPipModule {
pipMediaController,
tvPipNotificationController,
taskStackListener,
+ displayController,
windowManagerShellWrapper,
mainExecutor));
}
@@ -161,15 +162,14 @@ public abstract class TvPipModule {
PipAnimationController pipAnimationController,
PipTransitionController pipTransitionController,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
- Optional<LegacySplitScreenController> splitScreenOptional,
- Optional<SplitScreenController> newSplitScreenOptional,
+ Optional<SplitScreenController> splitScreenControllerOptional,
DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
@ShellMainThread ShellExecutor mainExecutor) {
return new PipTaskOrganizer(context,
syncTransactionQueue, pipTransitionState, tvPipBoundsState, tvPipBoundsAlgorithm,
tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper,
- pipTransitionController, splitScreenOptional, newSplitScreenOptional,
+ pipTransitionController, splitScreenControllerOptional,
displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 7879e7a5bb00..73f393140cbc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -285,15 +285,14 @@ public class WMShellModule {
PipAnimationController pipAnimationController,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
PipTransitionController pipTransitionController,
- Optional<LegacySplitScreenController> splitScreenOptional,
- Optional<SplitScreenController> newSplitScreenOptional,
+ Optional<SplitScreenController> splitScreenControllerOptional,
DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
@ShellMainThread ShellExecutor mainExecutor) {
return new PipTaskOrganizer(context,
syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
- pipTransitionController, splitScreenOptional, newSplitScreenOptional,
+ pipTransitionController, splitScreenControllerOptional,
displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 52ff21bc3172..fef9be36a35f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -110,6 +110,24 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
}
@Override
+ public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
+ if (!mTasks.contains(taskId)) {
+ throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
+ }
+ return mTasks.get(taskId).mLeash;
+ }
+
+ @Override
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + this);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 6e38e421d4b6..73e6cba43ec0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -133,10 +133,20 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
if (!mDataByTaskId.contains(taskId)) {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
- b.setParent(mDataByTaskId.get(taskId).surface);
+ return mDataByTaskId.get(taskId).surface;
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
index 86bf3ff1cea9..d2f42c39acd5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
@@ -343,10 +343,20 @@ class LegacySplitScreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
if (!mLeashByTaskId.contains(taskId)) {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
- b.setParent(mLeashByTaskId.get(taskId));
+ return mLeashByTaskId.get(taskId);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
index ddc85f758916..e03421dd58ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
@@ -47,12 +47,13 @@ interface IPip {
/**
* Notifies the swiping Activity to PiP onto home transition is finished
*
+ * @param taskId the Task id that the Activity and overlay are currently in.
* @param componentName ComponentName represents the Activity
* @param destinationBounds the destination bounds the PiP window lands into
* @param overlay an optional overlay to fade out after entering PiP
*/
- oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds,
- in SurfaceControl overlay) = 2;
+ oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
+ in Rect destinationBounds, in SurfaceControl overlay) = 2;
/**
* Sets listener to get pinned stack animation callbacks.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index bebf2cad83a4..ddcd4bd3a8e3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -28,14 +28,16 @@ import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
-import android.util.Log;
+import android.util.ArraySet;
import android.util.Size;
import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -43,6 +45,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.function.Consumer;
/**
@@ -90,6 +93,24 @@ public class PipBoundsState {
private int mShelfHeight;
/** Whether the user has resized the PIP manually. */
private boolean mHasUserResizedPip;
+ /**
+ * Areas defined by currently visible apps that they prefer to keep clear from overlays such as
+ * the PiP. Restricted areas may only move the PiP a limited amount from its anchor position.
+ * The system will try to respect these areas, but when not possible will ignore them.
+ *
+ * @see android.view.View#setPreferKeepClearRects
+ */
+ private final Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
+ /**
+ * Areas defined by currently visible apps holding
+ * {@link android.Manifest.permission#SET_UNRESTRICTED_KEEP_CLEAR_AREAS} that they prefer to
+ * keep clear from overlays such as the PiP.
+ * Unrestricted areas can move the PiP farther than restricted areas, and the system will try
+ * harder to respect these areas.
+ *
+ * @see android.view.View#setPreferKeepClearRects
+ */
+ private final Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
private @Nullable Runnable mOnMinimalSizeChangeCallback;
private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback;
@@ -203,7 +224,8 @@ public class PipBoundsState {
new PictureInPictureUiState(stashedState != STASH_TYPE_NONE /* isStashed */)
);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to set alert PiP state change.");
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Unable to set alert PiP state change.", TAG);
}
}
@@ -367,6 +389,25 @@ public class PipBoundsState {
}
}
+ /** Set the keep clear areas onscreen. The PiP should ideally not cover them. */
+ public void setKeepClearAreas(@NonNull Set<Rect> restrictedAreas,
+ @NonNull Set<Rect> unrestrictedAreas) {
+ mRestrictedKeepClearAreas.clear();
+ mRestrictedKeepClearAreas.addAll(restrictedAreas);
+ mUnrestrictedKeepClearAreas.clear();
+ mUnrestrictedKeepClearAreas.addAll(unrestrictedAreas);
+ }
+
+ @NonNull
+ public Set<Rect> getRestrictedKeepClearAreas() {
+ return mRestrictedKeepClearAreas;
+ }
+
+ @NonNull
+ public Set<Rect> getUnrestrictedKeepClearAreas() {
+ return mUnrestrictedKeepClearAreas;
+ }
+
/**
* Initialize states when first entering PiP.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 1eb9501ac076..b266189ec262 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -63,7 +63,6 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.util.Log;
import android.util.Rational;
import android.view.Display;
import android.view.Surface;
@@ -73,6 +72,7 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.animation.Interpolators;
@@ -81,8 +81,8 @@ import com.android.wm.shell.common.ScreenshotUtils;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.annotations.ShellMainThread;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
import com.android.wm.shell.pip.phone.PipMotionHelper;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
@@ -133,7 +133,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private final int mExitAnimationDuration;
private final int mCrossFadeAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
- private final Optional<LegacySplitScreenController> mLegacySplitScreenOptional;
private final Optional<SplitScreenController> mSplitScreenOptional;
protected final ShellTaskOrganizer mTaskOrganizer;
protected final ShellExecutor mMainExecutor;
@@ -249,7 +248,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
* An optional overlay used to mask content changing between an app in/out of PiP, only set if
* {@link PipTransitionState#getInSwipePipToHomeTransition()} is true.
*/
- private SurfaceControl mSwipePipToHomeOverlay;
+ @Nullable
+ SurfaceControl mSwipePipToHomeOverlay;
public PipTaskOrganizer(Context context,
@NonNull SyncTransactionQueue syncTransactionQueue,
@@ -260,7 +260,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
@NonNull PipAnimationController pipAnimationController,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
@NonNull PipTransitionController pipTransitionController,
- Optional<LegacySplitScreenController> legacySplitScreenOptional,
Optional<SplitScreenController> splitScreenOptional,
@NonNull DisplayController displayController,
@NonNull PipUiEventLogger pipUiEventLogger,
@@ -283,7 +282,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mPipAnimationController = pipAnimationController;
mPipUiEventLoggerLogger = pipUiEventLogger;
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
- mLegacySplitScreenOptional = legacySplitScreenOptional;
mSplitScreenOptional = splitScreenOptional;
mTaskOrganizer = shellTaskOrganizer;
mMainExecutor = mainExecutor;
@@ -356,12 +354,24 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
* Callback when launcher finishes swipe-pip-to-home operation.
* Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
*/
- public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+ public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
// do nothing if there is no startSwipePipToHome being called before
- if (mPipTransitionState.getInSwipePipToHomeTransition()) {
- mPipBoundsState.setBounds(destinationBounds);
- mSwipePipToHomeOverlay = overlay;
+ if (!mPipTransitionState.getInSwipePipToHomeTransition()) {
+ return;
+ }
+ mPipBoundsState.setBounds(destinationBounds);
+ mSwipePipToHomeOverlay = overlay;
+ if (ENABLE_SHELL_TRANSITIONS) {
+ // With Shell transition, the overlay was attached to the remote transition leash, which
+ // will be removed when the current transition is finished, so we need to reparent it
+ // to the actual Task surface now.
+ // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP
+ // transition.
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, t);
+ t.setLayer(overlay, Integer.MAX_VALUE);
+ t.apply();
}
}
@@ -395,8 +405,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (!mPipTransitionState.isInPip()
|| mPipTransitionState.getTransitionState() == PipTransitionState.EXITING_PIP
|| mToken == null) {
- Log.wtf(TAG, "Not allowed to exitPip in current state"
- + " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
+ ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Not allowed to exitPip in current state"
+ + " mState=%d mToken=%s", TAG, mPipTransitionState.getTransitionState(),
+ mToken);
return;
}
@@ -489,20 +501,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
wct.setWindowingMode(mToken, getOutPipWindowingMode());
// Simply reset the activity mode set prior to the animation running.
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- mLegacySplitScreenOptional.ifPresent(splitScreen -> {
- if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
- wct.reparent(mToken, splitScreen.getSecondaryRoot(), true /* onTop */);
- }
- });
}
/**
* Removes PiP immediately.
*/
public void removePip() {
- if (!mPipTransitionState.isInPip() || mToken == null) {
- Log.wtf(TAG, "Not allowed to removePip in current state"
- + " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
+ if (!mPipTransitionState.isInPip() || mToken == null) {
+ ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Not allowed to removePip in current state"
+ + " mState=%d mToken=%s", TAG, mPipTransitionState.getTransitionState(),
+ mToken);
return;
}
@@ -539,7 +548,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
ActivityTaskManager.getService().removeRootTasksInWindowingModes(
new int[]{ WINDOWING_MODE_PINNED });
} catch (RemoteException e) {
- Log.e(TAG, "Failed to remove PiP", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to remove PiP, %s",
+ TAG, e);
}
}
@@ -568,7 +579,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (!mWaitForFixedRotation) {
onEndOfSwipePipToHomeTransition();
} else {
- Log.d(TAG, "Defer onTaskAppeared-SwipePipToHome until end of fixed rotation.");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Defer onTaskAppeared-SwipePipToHome until end of fixed rotation.",
+ TAG);
}
return;
}
@@ -576,7 +589,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (mOneShotAnimationType == ANIM_TYPE_ALPHA
&& SystemClock.uptimeMillis() - mLastOneShotAlphaAnimationTime
> ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS) {
- Log.d(TAG, "Alpha animation is expired. Use bounds animation.");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Alpha animation is expired. Use bounds animation.", TAG);
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
}
@@ -613,8 +627,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private void onTaskAppearedWithFixedRotation() {
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
- Log.d(TAG, "Defer entering PiP alpha animation, fixed rotation is ongoing");
- // If deferred, hide the surface till fixed rotation is completed.
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Defer entering PiP alpha animation, fixed rotation is ongoing", TAG);
+ // If deferred, hside the surface till fixed rotation is completed.
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
tx.setAlpha(mLeash, 0f);
@@ -671,7 +686,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private void onEndOfSwipePipToHomeTransition() {
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- mSwipePipToHomeOverlay = null;
return;
}
@@ -763,7 +777,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final WindowContainerToken token = info.token;
Objects.requireNonNull(token, "Requires valid WindowContainerToken");
if (token.asBinder() != mToken.asBinder()) {
- Log.wtf(TAG, "Unrecognized token: " + token);
+ ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Unrecognized token: %s", TAG, token);
return;
}
onExitPipFinished(info);
@@ -788,8 +803,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
if (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP
&& mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP) {
- Log.d(TAG, "Defer onTaskInfoChange in current state: "
- + mPipTransitionState.getTransitionState());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Defer onTaskInfoChange in current state: %d", TAG,
+ mPipTransitionState.getTransitionState());
// Defer applying PiP parameters if the task is entering PiP to avoid disturbing
// the animation.
mDeferredTaskInfo = info;
@@ -800,7 +816,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mPipBoundsAlgorithm.getMinimalSize(info.topActivityInfo));
final PictureInPictureParams newParams = info.pictureInPictureParams;
if (newParams == null || !applyPictureInPictureParams(newParams)) {
- Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Ignored onTaskInfoChanged with PiP param: %s", TAG, newParams);
return;
}
// Aspect ratio changed, re-calculate bounds if valid.
@@ -823,6 +840,24 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
@Override
+ public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
+ if (mTaskInfo == null || mLeash == null || mTaskInfo.taskId != taskId) {
+ throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
+ }
+ return mLeash;
+ }
+
+ @Override
public void onFixedRotationStarted(int displayId, int newRotation) {
mNextRotation = newRotation;
mWaitForFixedRotation = true;
@@ -877,9 +912,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
clearWaitForFixedRotation();
}
- /** Called when exiting PIP tranisiton is finished to do the state cleanup. */
+ /** Called when exiting PIP transition is finished to do the state cleanup. */
void onExitPipFinished(TaskInfo info) {
clearWaitForFixedRotation();
+ if (mSwipePipToHomeOverlay != null) {
+ removeContentOverlay(mSwipePipToHomeOverlay, null /* callback */);
+ mSwipePipToHomeOverlay = null;
+ }
mPipTransitionState.setInSwipePipToHomeTransition(false);
mPictureInPictureParams = null;
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
@@ -895,7 +934,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private void fadeExistingPip(boolean show) {
if (mLeash == null || !mLeash.isValid()) {
- Log.w(TAG, "Invalid leash on fadeExistingPip: " + mLeash);
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Invalid leash on fadeExistingPip: %s", TAG, mLeash);
return;
}
final float alphaStart = show ? 0 : 1;
@@ -942,11 +982,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if ((mPipTransitionState.getInSwipePipToHomeTransition()
|| waitForFixedRotationOnEnteringPip) && fromRotation) {
if (DEBUG) {
- Log.d(TAG, "Skip onMovementBoundsChanged on rotation change"
- + " InSwipePipToHomeTransition="
- + mPipTransitionState.getInSwipePipToHomeTransition()
- + " mWaitForFixedRotation=" + mWaitForFixedRotation
- + " getTransitionState=" + mPipTransitionState.getTransitionState());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Skip onMovementBoundsChanged on rotation change"
+ + " InSwipePipToHomeTransition=%b"
+ + " mWaitForFixedRotation=%b"
+ + " getTransitionState=%d", TAG,
+ mPipTransitionState.getInSwipePipToHomeTransition(), mWaitForFixedRotation,
+ mPipTransitionState.getTransitionState());
}
return;
}
@@ -1061,7 +1103,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
@PipAnimationController.TransitionDirection int direction,
Consumer<Rect> updateBoundsCallback) {
if (mWaitForFixedRotation) {
- Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: skip scheduleAnimateResizePip, entering pip deferred", TAG);
return;
}
scheduleAnimateResizePip(mPipBoundsState.getBounds(), toBounds, 0 /* startingAngle */,
@@ -1075,7 +1118,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration,
float startingAngle, Consumer<Rect> updateBoundsCallback) {
if (mWaitForFixedRotation) {
- Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: skip scheduleAnimateResizePip, entering pip deferred", TAG);
return;
}
scheduleAnimateResizePip(fromBounds, toBounds, startingAngle, null /* sourceHintRect */,
@@ -1113,7 +1157,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
public void scheduleResizePip(Rect toBounds, Consumer<Rect> updateBoundsCallback) {
// Could happen when exitPip
if (mToken == null || mLeash == null) {
- Log.w(TAG, "Abort animation, invalid leash");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Abort animation, invalid leash", TAG);
return;
}
mPipBoundsState.setBounds(toBounds);
@@ -1148,12 +1193,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
Consumer<Rect> updateBoundsCallback) {
// Could happen when exitPip
if (mToken == null || mLeash == null) {
- Log.w(TAG, "Abort animation, invalid leash");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Abort animation, invalid leash", TAG);
return;
}
if (startBounds.isEmpty() || toBounds.isEmpty()) {
- Log.w(TAG, "Attempted to user resize PIP to or from empty bounds, aborting.");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Attempted to user resize PIP to or from empty bounds, aborting.", TAG);
return;
}
@@ -1228,7 +1275,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
if (mWaitForFixedRotation) {
- Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: skip scheduleOffsetPip, entering pip deferred", TAG);
return;
}
offsetPip(originalBounds, 0 /* xOffset */, offset, duration);
@@ -1241,7 +1289,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private void offsetPip(Rect originalBounds, int xOffset, int yOffset, int durationMs) {
if (mTaskInfo == null) {
- Log.w(TAG, "mTaskInfo is not set");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: mTaskInfo is not set",
+ TAG);
return;
}
final Rect destinationBounds = new Rect(originalBounds);
@@ -1386,7 +1435,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
float startingAngle) {
// Could happen when exitPip
if (mToken == null || mLeash == null) {
- Log.w(TAG, "Abort animation, invalid leash");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Abort animation, invalid leash", TAG);
return null;
}
final int rotationDelta = mWaitForFixedRotation
@@ -1453,36 +1503,21 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
/**
- * Sync with {@link LegacySplitScreenController} or {@link SplitScreenController} on destination
- * bounds if PiP is going to split screen.
+ * Sync with {@link SplitScreenController} on destination bounds if PiP is going to
+ * split screen.
*
* @param destinationBoundsOut contain the updated destination bounds if applicable
* @return {@code true} if destinationBounds is altered for split screen
*/
private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut, boolean enterSplit) {
- if (enterSplit && mSplitScreenOptional.isPresent()) {
- final Rect topLeft = new Rect();
- final Rect bottomRight = new Rect();
- mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);
- final boolean isPipTopLeft = isPipTopLeft();
- destinationBoundsOut.set(isPipTopLeft ? topLeft : bottomRight);
- return true;
- }
-
- if (!mLegacySplitScreenOptional.isPresent()) {
+ if (!enterSplit || !mSplitScreenOptional.isPresent()) {
return false;
}
-
- LegacySplitScreenController legacySplitScreen = mLegacySplitScreenOptional.get();
- if (!legacySplitScreen.isDividerVisible()) {
- // fail early if system is not in split screen mode
- return false;
- }
-
- // PiP window will go to split-secondary mode instead of fullscreen, populates the
- // split screen bounds here.
- destinationBoundsOut.set(legacySplitScreen.getDividerView()
- .getNonMinimizedSplitScreenSecondaryBounds());
+ final Rect topLeft = new Rect();
+ final Rect bottomRight = new Rect();
+ mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);
+ final boolean isPipTopLeft = isPipTopLeft();
+ destinationBoundsOut.set(isPipTopLeft ? topLeft : bottomRight);
return true;
}
@@ -1501,7 +1536,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
// Could happen if onTaskVanished happens during the animation since we may have
// set a start delay on this animation.
- Log.d(TAG, "Task vanished, skip fadeOutAndRemoveOverlay");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Task vanished, skip fadeOutAndRemoveOverlay", TAG);
animation.removeAllListeners();
animation.removeAllUpdateListeners();
animation.cancel();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index f01457bc4c95..be713a59a816 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -50,7 +50,6 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
-import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
@@ -61,8 +60,10 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.CounterRotatorHelper;
import com.android.wm.shell.transition.Transitions;
@@ -151,7 +152,7 @@ public class PipTransition extends PipTransitionController {
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- final TransitionInfo.Change currentPipChange = findCurrentPipChange(info);
+ final TransitionInfo.Change currentPipTaskChange = findCurrentPipTaskChange(info);
final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
mInFixedRotation = fixedRotationChange != null;
mEndFixedRotation = mInFixedRotation
@@ -171,22 +172,29 @@ public class PipTransition extends PipTransitionController {
throw new RuntimeException("Previous callback not called, aborting exit PIP.");
}
- if (currentPipChange == null) {
- throw new RuntimeException("Cannot find the pip window for exit-pip transition.");
+ // PipTaskChange can be null if the PIP task has been detached, for example, when the
+ // task contains multiple activities, the PIP will be moved to a new PIP task when
+ // entering, and be moved back when exiting. In that case, the PIP task will be removed
+ // immediately.
+ final TaskInfo pipTaskInfo = currentPipTaskChange != null
+ ? currentPipTaskChange.getTaskInfo()
+ : mPipOrganizer.getTaskInfo();
+ if (pipTaskInfo == null) {
+ throw new RuntimeException("Cannot find the pip task for exit-pip transition.");
}
switch (type) {
case TRANSIT_EXIT_PIP:
startExitAnimation(info, startTransaction, finishTransaction, finishCallback,
- currentPipChange);
+ pipTaskInfo, currentPipTaskChange);
break;
case TRANSIT_EXIT_PIP_TO_SPLIT:
startExitToSplitAnimation(info, startTransaction, finishTransaction,
- finishCallback, currentPipChange);
+ finishCallback, pipTaskInfo);
break;
case TRANSIT_REMOVE_PIP:
removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
- currentPipChange);
+ pipTaskInfo);
break;
default:
throw new IllegalStateException("mExitTransition with unexpected transit type="
@@ -199,9 +207,9 @@ public class PipTransition extends PipTransitionController {
// The previous PIP Task is no longer in PIP, but this is not an exit transition (This can
// happen when a new activity requests enter PIP). In this case, we just show this Task in
// its end state, and play other animation as normal.
- if (currentPipChange != null
- && currentPipChange.getTaskInfo().getWindowingMode() != WINDOWING_MODE_PINNED) {
- resetPrevPip(currentPipChange, startTransaction);
+ if (currentPipTaskChange != null
+ && currentPipTaskChange.getTaskInfo().getWindowingMode() != WINDOWING_MODE_PINNED) {
+ resetPrevPip(currentPipTaskChange, startTransaction);
}
// Entering PIP.
@@ -211,8 +219,9 @@ public class PipTransition extends PipTransitionController {
// For transition that we don't animate, but contains the PIP leash, we need to update the
// PIP surface, otherwise it will be reset after the transition.
- if (currentPipChange != null) {
- updatePipForUnhandledTransition(currentPipChange, startTransaction, finishTransaction);
+ if (currentPipTaskChange != null) {
+ updatePipForUnhandledTransition(currentPipTaskChange, startTransaction,
+ finishTransaction);
}
// Fade in the fadeout PIP when the fixed rotation is finished.
@@ -321,7 +330,7 @@ public class PipTransition extends PipTransitionController {
}
@Nullable
- private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) {
+ private TransitionInfo.Change findCurrentPipTaskChange(@NonNull TransitionInfo info) {
if (mCurrentPipTaskToken == null) {
return null;
}
@@ -349,9 +358,30 @@ public class PipTransition extends PipTransitionController {
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
- @NonNull TransitionInfo.Change pipChange) {
+ @NonNull TaskInfo taskInfo, @Nullable TransitionInfo.Change pipTaskChange) {
+ TransitionInfo.Change pipChange = pipTaskChange;
+ if (pipChange == null) {
+ // The pipTaskChange is null, this can happen if we are reparenting the PIP activity
+ // back to its original Task. In that case, we should animate the activity leash
+ // instead, which should be the only non-task, independent, TRANSIT_CHANGE window.
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.getTaskInfo() == null && change.getMode() == TRANSIT_CHANGE
+ && TransitionInfo.isIndependent(change, info)) {
+ pipChange = change;
+ break;
+ }
+ }
+ }
+ if (pipChange == null) {
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: No window of exiting PIP is found. Can't play expand animation", TAG);
+ removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
+ taskInfo);
+ return;
+ }
mFinishCallback = (wct, wctCB) -> {
- mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+ mPipOrganizer.onExitPipFinished(taskInfo);
finishCallback.onTransitionFinished(wct, wctCB);
};
mFinishTransaction = finishTransaction;
@@ -371,7 +401,7 @@ public class PipTransition extends PipTransitionController {
if (displayRotationChange != null) {
// Exiting PIP to fullscreen with orientation change.
startExpandAndRotationAnimation(info, startTransaction, finishTransaction,
- displayRotationChange, pipChange);
+ displayRotationChange, taskInfo, pipChange);
return;
}
}
@@ -412,15 +442,14 @@ public class PipTransition extends PipTransitionController {
} else {
rotationDelta = Surface.ROTATION_0;
}
- startExpandAnimation(pipChange.getTaskInfo(), pipChange.getLeash(), destinationBounds,
- rotationDelta);
+ startExpandAnimation(taskInfo, pipChange.getLeash(), destinationBounds, rotationDelta);
}
private void startExpandAndRotationAnimation(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull TransitionInfo.Change displayRotationChange,
- @NonNull TransitionInfo.Change pipChange) {
+ @NonNull TaskInfo taskInfo, @NonNull TransitionInfo.Change pipChange) {
final int rotateDelta = deltaRotation(displayRotationChange.getStartRotation(),
displayRotationChange.getEndRotation());
@@ -458,7 +487,7 @@ public class PipTransition extends PipTransitionController {
// Expand and rotate the pip window to fullscreen.
final PipAnimationController.PipTransitionAnimator animator =
- mPipAnimationController.getAnimator(pipChange.getTaskInfo(), pipChange.getLeash(),
+ mPipAnimationController.getAnimator(taskInfo, pipChange.getLeash(),
startBounds, startBounds, endBounds, null, TRANSITION_DIRECTION_LEAVE_PIP,
0 /* startingAngle */, pipRotateDelta);
animator.setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP)
@@ -484,11 +513,11 @@ public class PipTransition extends PipTransitionController {
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
- @NonNull TransitionInfo.Change pipChange) {
+ @NonNull TaskInfo taskInfo) {
startTransaction.apply();
finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
mPipBoundsState.getDisplayBounds());
- mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+ mPipOrganizer.onExitPipFinished(taskInfo);
finishCallback.onTransitionFinished(null, null);
}
@@ -603,11 +632,18 @@ public class PipTransition extends PipTransitionController {
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
- SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
- tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
+ final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mSwipePipToHomeOverlay;
+ startTransaction.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
.setPosition(leash, destinationBounds.left, destinationBounds.top)
.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height());
- startTransaction.merge(tx);
+ if (swipePipToHomeOverlay != null) {
+ // Launcher fade in the overlay on top of the fullscreen Task. It is possible we
+ // reparent the PIP activity to a new PIP task (in case there are other activities
+ // in the original Task), so we should also reparent the overlay to the PIP task.
+ startTransaction.reparent(swipePipToHomeOverlay, leash)
+ .setLayer(swipePipToHomeOverlay, Integer.MAX_VALUE);
+ mPipOrganizer.mSwipePipToHomeOverlay = null;
+ }
startTransaction.apply();
if (rotationDelta != Surface.ROTATION_0 && mInFixedRotation) {
// For fixed rotation, set the destination bounds to the new rotation coordinates
@@ -617,6 +653,10 @@ public class PipTransition extends PipTransitionController {
mPipBoundsState.setBounds(destinationBounds);
onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */);
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
+ if (swipePipToHomeOverlay != null) {
+ mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
+ null /* callback */, false /* withStartDelay */);
+ }
mPipTransitionState.setInSwipePipToHomeTransition(false);
return true;
}
@@ -677,11 +717,11 @@ public class PipTransition extends PipTransitionController {
}
}
- private void startExitToSplitAnimation(TransitionInfo info,
- SurfaceControl.Transaction startTransaction,
- SurfaceControl.Transaction finishTransaction,
- Transitions.TransitionFinishCallback finishCallback,
- TransitionInfo.Change pipChange) {
+ private void startExitToSplitAnimation(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback,
+ @NonNull TaskInfo taskInfo) {
final int changeSize = info.getChanges().size();
if (changeSize < 4) {
throw new RuntimeException(
@@ -709,15 +749,15 @@ public class PipTransition extends PipTransitionController {
mSplitScreenOptional.get().finishEnterSplitScreen(startTransaction);
startTransaction.apply();
- mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+ mPipOrganizer.onExitPipFinished(taskInfo);
finishCallback.onTransitionFinished(null, null);
}
- private void resetPrevPip(@NonNull TransitionInfo.Change prevPipChange,
+ private void resetPrevPip(@NonNull TransitionInfo.Change prevPipTaskChange,
@NonNull SurfaceControl.Transaction startTransaction) {
- final SurfaceControl leash = prevPipChange.getLeash();
- final Rect bounds = prevPipChange.getEndAbsBounds();
- final Point offset = prevPipChange.getEndRelOffset();
+ final SurfaceControl leash = prevPipTaskChange.getLeash();
+ final Rect bounds = prevPipTaskChange.getEndAbsBounds();
+ final Point offset = prevPipTaskChange.getEndRelOffset();
bounds.offset(-offset.x, -offset.y);
startTransaction.setWindowCrop(leash, null);
@@ -725,7 +765,7 @@ public class PipTransition extends PipTransitionController {
startTransaction.setCornerRadius(leash, 0);
startTransaction.setPosition(leash, bounds.left, bounds.top);
- if (mHasFadeOut && prevPipChange.getTaskInfo().isVisible()) {
+ if (mHasFadeOut && prevPipTaskChange.getTaskInfo().isVisible()) {
if (mPipAnimationController.getCurrentAnimator() != null) {
mPipAnimationController.getCurrentAnimator().cancel();
}
@@ -733,7 +773,7 @@ public class PipTransition extends PipTransitionController {
}
mHasFadeOut = false;
mCurrentPipTaskToken = null;
- mPipOrganizer.onExitPipFinished(prevPipChange.getTaskInfo());
+ mPipOrganizer.onExitPipFinished(prevPipTaskChange.getTaskInfo());
}
private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
@@ -757,7 +797,8 @@ public class PipTransition extends PipTransitionController {
final SurfaceControl leash = mPipOrganizer.getSurfaceControl();
final TaskInfo taskInfo = mPipOrganizer.getTaskInfo();
if (leash == null || !leash.isValid() || taskInfo == null) {
- Log.w(TAG, "Invalid leash on fadeExistingPip: " + leash);
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Invalid leash on fadeExistingPip: %s", TAG, leash);
return;
}
final float alphaStart = show ? 0 : 1;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
index da6d9804b29d..d7b69adf1241 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
@@ -24,9 +24,11 @@ import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
-import android.util.Log;
import android.util.Pair;
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
/** A class that includes convenience methods. */
public class PipUtils {
private static final String TAG = "PipUtils";
@@ -51,7 +53,8 @@ public class PipUtils {
}
}
} catch (RemoteException e) {
- Log.w(TAG, "Unable to get pinned stack.");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Unable to get pinned stack.", TAG);
}
return new Pair<>(null, 0);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 71cff025a7a8..c4dadf1f739a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -29,7 +29,6 @@ import android.graphics.RectF;
import android.os.Debug;
import android.os.Handler;
import android.os.RemoteException;
-import android.util.Log;
import android.util.Size;
import android.view.MotionEvent;
import android.view.SurfaceControl;
@@ -37,6 +36,7 @@ import android.view.SyncRtSurfaceTransactionApplier;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.WindowManagerGlobal;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.pip.PipBoundsState;
@@ -44,6 +44,7 @@ import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipMediaController.ActionListener;
import com.android.wm.shell.pip.PipMenuController;
import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
import java.io.PrintWriter;
@@ -285,13 +286,15 @@ public class PhonePipMenuController implements PipMenuController {
private void showMenuInternal(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) {
if (DEBUG) {
- Log.d(TAG, "showMenu() state=" + menuState
- + " isMenuVisible=" + isMenuVisible()
- + " allowMenuTimeout=" + allowMenuTimeout
- + " willResizeMenu=" + willResizeMenu
- + " withDelay=" + withDelay
- + " showResizeHandle=" + showResizeHandle
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showMenu() state=%s"
+ + " isMenuVisible=%s"
+ + " allowMenuTimeout=%s"
+ + " willResizeMenu=%s"
+ + " withDelay=%s"
+ + " showResizeHandle=%s"
+ + " callers=\n%s", TAG, menuState, isMenuVisible(), allowMenuTimeout,
+ willResizeMenu, withDelay, showResizeHandle, Debug.getCallers(5, " "));
}
if (!maybeCreateSyncApplier()) {
@@ -383,7 +386,8 @@ public class PhonePipMenuController implements PipMenuController {
private boolean maybeCreateSyncApplier() {
if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
- Log.v(TAG, "Not going to move PiP, either menu or its parent is not created.");
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Not going to move PiP, either menu or its parent is not created.", TAG);
return false;
}
@@ -400,7 +404,8 @@ public class PhonePipMenuController implements PipMenuController {
public void pokeMenu() {
final boolean isMenuVisible = isMenuVisible();
if (DEBUG) {
- Log.d(TAG, "pokeMenu() isMenuVisible=" + isMenuVisible);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: pokeMenu() isMenuVisible=%b", TAG, isMenuVisible);
}
if (isMenuVisible) {
mPipMenuView.pokeMenu();
@@ -410,7 +415,8 @@ public class PhonePipMenuController implements PipMenuController {
private void fadeOutMenu() {
final boolean isMenuVisible = isMenuVisible();
if (DEBUG) {
- Log.d(TAG, "fadeOutMenu() isMenuVisible=" + isMenuVisible);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: fadeOutMenu() isMenuVisible=%b", TAG, isMenuVisible);
}
if (isMenuVisible) {
mPipMenuView.fadeOutMenu();
@@ -436,11 +442,14 @@ public class PhonePipMenuController implements PipMenuController {
public void hideMenu(@PipMenuView.AnimationType int animationType, boolean resize) {
final boolean isMenuVisible = isMenuVisible();
if (DEBUG) {
- Log.d(TAG, "hideMenu() state=" + mMenuState
- + " isMenuVisible=" + isMenuVisible
- + " animationType=" + animationType
- + " resize=" + resize
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: hideMenu() state=%s"
+ + " isMenuVisible=%s"
+ + " animationType=%s"
+ + " resize=%s"
+ + " callers=\n%s", TAG, mMenuState, isMenuVisible,
+ animationType, resize,
+ Debug.getCallers(5, " "));
}
if (isMenuVisible) {
mPipMenuView.hideMenu(resize, animationType);
@@ -516,9 +525,11 @@ public class PhonePipMenuController implements PipMenuController {
*/
void onMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
if (DEBUG) {
- Log.d(TAG, "onMenuStateChangeStart() mMenuState=" + mMenuState
- + " menuState=" + menuState + " resize=" + resize
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onMenuStateChangeStart() mMenuState=%s"
+ + " menuState=%s resize=%s"
+ + " callers=\n%s", TAG, mMenuState, menuState, resize,
+ Debug.getCallers(5, " "));
}
if (menuState != mMenuState) {
@@ -538,7 +549,8 @@ public class PhonePipMenuController implements PipMenuController {
mSystemWindows.getFocusGrantToken(mPipMenuView),
menuState != MENU_STATE_NONE /* grantFocus */);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to update focus as menu appears/disappears", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Unable to update focus as menu appears/disappears, %s", TAG, e);
}
}
}
@@ -584,9 +596,11 @@ public class PhonePipMenuController implements PipMenuController {
public void updateMenuLayout(Rect bounds) {
final boolean isMenuVisible = isMenuVisible();
if (DEBUG) {
- Log.d(TAG, "updateMenuLayout() state=" + mMenuState
- + " isMenuVisible=" + isMenuVisible
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateMenuLayout() state=%s"
+ + " isMenuVisible=%s"
+ + " callers=\n%s", TAG, mMenuState, isMenuVisible,
+ Debug.getCallers(5, " "));
}
if (isMenuVisible) {
mPipMenuView.updateMenuLayout(bounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index d3dc91515921..e7a1c4cca07e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -46,10 +46,8 @@ import android.graphics.Rect;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.Log;
import android.util.Pair;
import android.util.Size;
-import android.util.Slog;
import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.WindowManagerGlobal;
@@ -61,6 +59,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayChangeController;
@@ -85,6 +84,7 @@ import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipUtils;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
@@ -282,7 +282,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
Optional<OneHandedController> oneHandedController,
ShellExecutor mainExecutor) {
if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
- Slog.w(TAG, "Device doesn't support Pip feature");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Device doesn't support Pip feature", TAG);
return null;
}
@@ -375,7 +376,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
try {
mWindowManagerShellWrapper.addPinnedStackListener(mPinnedTaskListener);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to register pinned stack listener", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to register pinned stack listener, %s", TAG, e);
}
try {
@@ -387,7 +389,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
mPipInputConsumer.registerInputConsumer();
}
} catch (RemoteException | UnsupportedOperationException e) {
- Log.e(TAG, "Failed to register pinned stack listener", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to register pinned stack listener, %s", TAG, e);
e.printStackTrace();
}
@@ -592,9 +595,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
return entryBounds;
}
- private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+ private void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
- mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds, overlay);
+ mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
}
private String getTransitionTag(int direction) {
@@ -724,7 +727,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
.getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (pinnedTaskInfo == null) return false;
} catch (RemoteException e) {
- Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to get RootTaskInfo for pinned task, %s", TAG, e);
return false;
}
final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
@@ -870,7 +874,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
PipController.this.dump(pw);
});
} catch (InterruptedException e) {
- Slog.e(TAG, "Failed to dump PipController in 2s");
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to dump PipController in 2s", TAG);
}
}
}
@@ -923,11 +928,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb
}
@Override
- public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
- SurfaceControl overlay) {
+ public void stopSwipePipToHome(int taskId, ComponentName componentName,
+ Rect destinationBounds, SurfaceControl overlay) {
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
(controller) -> {
- controller.stopSwipePipToHome(componentName, destinationBounds, overlay);
+ controller.stopSwipePipToHome(taskId, componentName, destinationBounds,
+ overlay);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
index 6e3a20d5f2b2..e57abc28bd0a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -22,14 +22,15 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
-import android.util.Log;
import android.view.BatchedInputEventReceiver;
import android.view.Choreographer;
import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.InputEvent;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.io.PrintWriter;
@@ -141,7 +142,8 @@ public class PipInputConsumer {
mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
} catch (RemoteException e) {
- Log.e(TAG, "Failed to create input consumer", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to create input consumer, %s", TAG, e);
}
mMainExecutor.execute(() -> {
// Choreographer.getSfInstance() must be called on the thread that the input event
@@ -165,7 +167,8 @@ public class PipInputConsumer {
// TODO(b/113087003): Support Picture-in-picture in multi-display.
mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
} catch (RemoteException e) {
- Log.e(TAG, "Failed to destroy input consumer", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to destroy input consumer, %s", TAG, e);
}
mInputEventReceiver.dispose();
mInputEventReceiver = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 225305bd5178..c0fa8c0a8898 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -47,7 +47,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
-import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.KeyEvent;
@@ -60,11 +59,13 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipUtils;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
import java.lang.annotation.Retention;
@@ -423,7 +424,7 @@ public class PipMenuView extends FrameLayout {
/**
* @return Estimated minimum {@link Size} to hold the actions.
- * See also {@link #updateActionViews(Rect)}
+ * See also {@link #updateActionViews(Rect)}
*/
Size getEstimatedMinMenuSize() {
final int pipActionSize = getResources().getDimensionPixelSize(R.dimen.pip_action_size);
@@ -505,7 +506,8 @@ public class PipMenuView extends FrameLayout {
try {
action.getActionIntent().send();
} catch (CanceledException e) {
- Log.w(TAG, "Failed to send action", e);
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to send action, %s", TAG, e);
}
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index 96fd59f0c911..f3789fd5a3d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -34,12 +34,12 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Debug;
import android.os.Looper;
-import android.util.Log;
import android.view.Choreographer;
import androidx.dynamicanimation.animation.AnimationHandler;
import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.FloatProperties;
import com.android.wm.shell.animation.PhysicsAnimator;
@@ -49,6 +49,7 @@ import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.function.Consumer;
@@ -354,8 +355,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
*/
private void expandLeavePip(boolean skipAnimation, boolean enterSplit) {
if (DEBUG) {
- Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: exitPip: skipAnimation=%s"
+ + " callers=\n%s", TAG, skipAnimation, Debug.getCallers(5, " "));
}
cancelPhysicsAnimation();
mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
@@ -368,7 +370,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
@Override
public void dismissPip() {
if (DEBUG) {
- Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: removePip: callers=\n%s", TAG, Debug.getCallers(5, " "));
}
cancelPhysicsAnimation();
mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
@@ -552,8 +555,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
*/
void animateToOffset(Rect originalBounds, int offset) {
if (DEBUG) {
- Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: animateToOffset: originalBounds=%s offset=%s"
+ + " callers=\n%s", TAG, originalBounds, offset,
+ Debug.getCallers(5, " "));
}
cancelPhysicsAnimation();
mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
@@ -671,8 +676,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
*/
private void resizePipUnchecked(Rect toBounds) {
if (DEBUG) {
- Log.d(TAG, "resizePipUnchecked: toBounds=" + toBounds
- + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: resizePipUnchecked: toBounds=%s"
+ + " callers=\n%s", TAG, toBounds, Debug.getCallers(5, " "));
}
if (!toBounds.equals(getBounds())) {
mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback);
@@ -684,8 +690,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
*/
private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
if (DEBUG) {
- Log.d(TAG, "resizeAndAnimatePipUnchecked: toBounds=" + toBounds
- + " duration=" + duration + " callers=\n" + Debug.getCallers(5, " "));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: resizeAndAnimatePipUnchecked: toBounds=%s"
+ + " duration=%s callers=\n%s", TAG, toBounds, duration,
+ Debug.getCallers(5, " "));
}
// Intentionally resize here even if the current bounds match the destination bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 350f2856e2bc..147a272f4645 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -35,7 +35,6 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.provider.DeviceConfig;
-import android.util.Log;
import android.util.Size;
import android.view.InputEvent;
import android.view.MotionEvent;
@@ -46,6 +45,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
@@ -54,6 +54,7 @@ import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.io.PrintWriter;
@@ -1010,7 +1011,8 @@ public class PipTouchHandler {
}
final Size estimatedMinMenuSize = mMenuController.getEstimatedMinMenuSize();
if (estimatedMinMenuSize == null) {
- Log.wtf(TAG, "Failed to get estimated menu size");
+ ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to get estimated menu size", TAG);
return false;
}
final Rect currentBounds = mPipBoundsState.getBounds();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
index 53303ff2b679..d7d69f27f9f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -17,15 +17,15 @@
package com.android.wm.shell.pip.phone;
import android.graphics.PointF;
-import android.os.Handler;
-import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.io.PrintWriter;
@@ -104,7 +104,8 @@ public class PipTouchState {
mActivePointerId = ev.getPointerId(0);
if (DEBUG) {
- Log.e(TAG, "Setting active pointer id on DOWN: " + mActivePointerId);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Setting active pointer id on DOWN: %d", TAG, mActivePointerId);
}
mLastTouch.set(ev.getRawX(), ev.getRawY());
mDownTouch.set(mLastTouch);
@@ -131,7 +132,8 @@ public class PipTouchState {
addMovementToVelocityTracker(ev);
int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) {
- Log.e(TAG, "Invalid active pointer id on MOVE: " + mActivePointerId);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Invalid active pointer id on MOVE: %d", TAG, mActivePointerId);
break;
}
@@ -168,8 +170,9 @@ public class PipTouchState {
final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
if (DEBUG) {
- Log.e(TAG,
- "Relinquish active pointer id on POINTER_UP: " + mActivePointerId);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Relinquish active pointer id on POINTER_UP: %d",
+ TAG, mActivePointerId);
}
mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));
}
@@ -189,7 +192,8 @@ public class PipTouchState {
int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) {
- Log.e(TAG, "Invalid active pointer id on UP: " + mActivePointerId);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Invalid active pointer id on UP: %d", TAG, mActivePointerId);
break;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
new file mode 100644
index 000000000000..85441af9a870
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
@@ -0,0 +1,2 @@
+# WM shell sub-module TV pip owner
+galinap@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 50691803e8f9..3c830e0a0d62 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -37,6 +37,7 @@ import android.view.Gravity;
import com.android.wm.shell.R;
import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerCallback;
@@ -50,12 +51,14 @@ import com.android.wm.shell.pip.PipTransitionController;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
/**
* Manages the picture-in-picture (PIP) UI and states.
*/
public class TvPipController implements PipTransitionController.PipTransitionCallback,
- TvPipMenuController.Delegate, TvPipNotificationController.Delegate {
+ TvPipMenuController.Delegate, TvPipNotificationController.Delegate,
+ DisplayController.OnDisplaysChangedListener {
private static final String TAG = "TvPipController";
static final boolean DEBUG = false;
@@ -112,6 +115,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
PipMediaController pipMediaController,
TvPipNotificationController pipNotificationController,
TaskStackListenerImpl taskStackListener,
+ DisplayController displayController,
WindowManagerShellWrapper wmShell,
ShellExecutor mainExecutor) {
return new TvPipController(
@@ -124,6 +128,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
pipMediaController,
pipNotificationController,
taskStackListener,
+ displayController,
wmShell,
mainExecutor).mImpl;
}
@@ -138,6 +143,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
PipMediaController pipMediaController,
TvPipNotificationController pipNotificationController,
TaskStackListenerImpl taskStackListener,
+ DisplayController displayController,
WindowManagerShellWrapper wmShell,
ShellExecutor mainExecutor) {
mContext = context;
@@ -163,6 +169,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
registerTaskStackListenerCallback(taskStackListener);
registerWmShellPinnedStackListener(wmShell);
+ displayController.addDisplayWindowListener(this);
}
private void onConfigurationChanged(Configuration newConfig) {
@@ -253,6 +260,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
return mTvPipBoundsState.getTvFixedPipOrientation();
}
+ @Override
+ public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+ Set<Rect> unrestricted) {
+ if (mTvPipBoundsState.getDisplayId() == displayId) {
+ mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted);
+ movePinnedStack();
+ }
+ }
+
/**
* Animate to the updated position of the PiP based on the state and position of the PiP.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index 1ddc0e7abeaf..64017e176fc3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -38,6 +38,8 @@ public enum ShellProtoLogGroup implements IProtoLogGroup {
"ShellBackPreview"),
WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM_SHELL),
+ WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG,
+ false, Consts.TAG_WM_SHELL),
TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");
private final boolean mEnabled;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index c5aab45f56fa..109f96e166d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -280,10 +280,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
if (mRootTaskInfo.taskId == taskId) {
- b.setParent(mRootLeash);
+ return mRootLeash;
} else if (mChildrenLeashes.contains(taskId)) {
- b.setParent(mChildrenLeashes.get(taskId));
+ return mChildrenLeashes.get(taskId);
} else {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
index 8b36c9406b15..7b679580fa87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
@@ -227,10 +227,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+ b.setParent(findTaskSurface(taskId));
+ }
+
+ @Override
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ t.reparent(sc, findTaskSurface(taskId));
+ }
+
+ private SurfaceControl findTaskSurface(int taskId) {
if (mRootTaskInfo.taskId == taskId) {
- b.setParent(mRootLeash);
+ return mRootLeash;
} else if (mChildrenLeashes.contains(taskId)) {
- b.setParent(mChildrenLeashes.get(taskId));
+ return mChildrenLeashes.get(taskId);
} else {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 56d51687603a..a225f4ec8349 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -408,7 +408,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|| type == TRANSIT_CLOSE
|| type == TRANSIT_TO_FRONT
|| type == TRANSIT_TO_BACK;
- if (isOpenOrCloseTransition) {
+ final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0;
+ if (isOpenOrCloseTransition && !isTranslucent) {
// Use the overview background as the background for the animation
final Context uiContext = ActivityThread.currentActivityThread()
.getSystemUiContext();
@@ -729,14 +730,17 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
: R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
} else if (type == TRANSIT_OPEN) {
- if (isTask) {
+ // We will translucent open animation for translucent activities and tasks. Choose
+ // WindowAnimation_activityOpenEnterAnimation and set translucent here, then
+ // TransitionAnimation loads appropriate animation later.
+ if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
+ translucent = true;
+ }
+ if (isTask && !translucent) {
animAttr = enter
? R.styleable.WindowAnimation_taskOpenEnterAnimation
: R.styleable.WindowAnimation_taskOpenExitAnimation;
} else {
- if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
- translucent = true;
- }
animAttr = enter
? R.styleable.WindowAnimation_activityOpenEnterAnimation
: R.styleable.WindowAnimation_activityOpenExitAnimation;
@@ -770,7 +774,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
animAttr, translucent);
} else {
- a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr);
+ a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index efb52a5b4644..610d2cc39445 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -363,7 +363,9 @@ public class Transitions implements RemoteCallable<Transitions> {
return;
}
- // apply transfer starting window directly if there is no other task change.
+ // apply transfer starting window directly if there is no other task change. Since this
+ // is an activity->activity situation, we can detect it by selecting transitions with only
+ // 2 changes where neither are tasks and one is a starting-window recipient.
final int changeSize = info.getChanges().size();
if (changeSize == 2) {
boolean nonTaskChange = true;
@@ -380,7 +382,9 @@ public class Transitions implements RemoteCallable<Transitions> {
}
if (nonTaskChange && transferStartingWindow) {
t.apply();
- onFinish(transitionToken, null /* wct */, null /* wctCB */);
+ // Treat this as an abort since we are bypassing any merge logic and effectively
+ // finishing immediately.
+ onAbort(transitionToken);
return;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 29e40be457d1..a31b28737552 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -325,17 +325,17 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
- public void testChangeLayoutsVisibilityOnKeyguardOccludedChanged() {
+ public void testChangeLayoutsVisibilityOnKeyguardShowingChanged() {
mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
- // Verify that the restart button is hidden after keyguard becomes occluded.
- mController.onKeyguardOccludedChanged(true);
+ // Verify that the restart button is hidden after keyguard becomes showing.
+ mController.onKeyguardShowingChanged(true);
verify(mMockCompatLayout).updateVisibility(false);
verify(mMockLetterboxEduLayout).updateVisibility(false);
- // Verify button remains hidden while keyguard is occluded.
+ // Verify button remains hidden while keyguard is showing.
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
@@ -345,20 +345,20 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockLetterboxEduLayout).updateCompatInfo(taskInfo, mMockTaskListener, /* canShow= */
false);
- // Verify button is shown after keyguard becomes not occluded.
- mController.onKeyguardOccludedChanged(false);
+ // Verify button is shown after keyguard becomes not showing.
+ mController.onKeyguardShowingChanged(false);
verify(mMockCompatLayout).updateVisibility(true);
verify(mMockLetterboxEduLayout).updateVisibility(true);
}
@Test
- public void testLayoutsRemainHiddenOnKeyguardOccludedFalseWhenImeIsShowing() {
+ public void testLayoutsRemainHiddenOnKeyguardShowingFalseWhenImeIsShowing() {
mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
- mController.onKeyguardOccludedChanged(true);
+ mController.onKeyguardShowingChanged(true);
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -366,8 +366,8 @@ public class CompatUIControllerTest extends ShellTestCase {
clearInvocations(mMockCompatLayout);
clearInvocations(mMockLetterboxEduLayout);
- // Verify button remains hidden after keyguard becomes not occluded since IME is showing.
- mController.onKeyguardOccludedChanged(false);
+ // Verify button remains hidden after keyguard becomes not showing since IME is showing.
+ mController.onKeyguardShowingChanged(false);
verify(mMockCompatLayout).updateVisibility(false);
verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -380,12 +380,12 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
- public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsOccluded() {
+ public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsShowing() {
mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
- mController.onKeyguardOccludedChanged(true);
+ mController.onKeyguardShowingChanged(true);
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -393,14 +393,14 @@ public class CompatUIControllerTest extends ShellTestCase {
clearInvocations(mMockCompatLayout);
clearInvocations(mMockLetterboxEduLayout);
- // Verify button remains hidden after IME is hidden since keyguard is occluded.
+ // Verify button remains hidden after IME is hidden since keyguard is showing.
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ false);
verify(mMockCompatLayout).updateVisibility(false);
verify(mMockLetterboxEduLayout).updateVisibility(false);
- // Verify button is shown after keyguard becomes not occluded.
- mController.onKeyguardOccludedChanged(false);
+ // Verify button is shown after keyguard becomes not showing.
+ mController.onKeyguardShowingChanged(false);
verify(mMockCompatLayout).updateVisibility(true);
verify(mMockLetterboxEduLayout).updateVisibility(true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
index 00e4938d866c..1dee88c43806 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
@@ -70,6 +70,8 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
public void testOnFinishInflate() {
assertEquals(mLayout.getDialogContainer(),
mLayout.findViewById(R.id.letterbox_education_dialog_container));
+ assertEquals(mLayout.getDialogTitle(),
+ mLayout.findViewById(R.id.letterbox_education_dialog_title));
assertEquals(mLayout.getBackgroundDim(), mLayout.getBackground());
assertEquals(mLayout.getBackground().getAlpha(), 0);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
index 0509dd38abe0..337b7385faec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
@@ -41,9 +41,11 @@ import android.testing.AndroidTestingRunner;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.SurfaceControlViewHost;
+import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
import androidx.test.filters.SmallTest;
@@ -173,13 +175,19 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
verifyLayout(layout, mWindowAttrsCaptor.getValue(), /* expectedWidth= */ TASK_WIDTH,
/* expectedHeight= */ TASK_HEIGHT, /* expectedExtraTopMargin= */ DISPLAY_CUTOUT_TOP,
/* expectedExtraBottomMargin= */ DISPLAY_CUTOUT_BOTTOM);
+ View dialogTitle = layout.getDialogTitle();
+ assertNotNull(dialogTitle);
+ spyOn(dialogTitle);
// Clicking the layout does nothing until enter animation is done.
layout.performClick();
verify(mAnimationController, never()).startExitAnimation(any(), any());
+ // The dialog title shouldn't be focused for Accessibility until enter animation is done.
+ verify(dialogTitle, never()).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
verifyAndFinishEnterAnimation(layout);
+ verify(dialogTitle).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
// Exit animation should start following a click on the layout.
layout.performClick();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 0172cf324eea..14d9fb9babc4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -48,7 +48,6 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -76,7 +75,6 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Mock private PipTransitionController mMockPipTransitionController;
@Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
@Mock private PipUiEventLogger mMockPipUiEventLogger;
- @Mock private Optional<LegacySplitScreenController> mMockOptionalLegacySplitScreen;
@Mock private Optional<SplitScreenController> mMockOptionalSplitScreen;
@Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
private TestShellExecutor mMainExecutor;
@@ -101,8 +99,8 @@ public class PipTaskOrganizerTest extends ShellTestCase {
mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
mPipBoundsAlgorithm, mMockPhonePipMenuController,
mMockPipAnimationController, mMockPipSurfaceTransactionHelper,
- mMockPipTransitionController, mMockOptionalLegacySplitScreen,
- mMockOptionalSplitScreen, mMockDisplayController, mMockPipUiEventLogger,
+ mMockPipTransitionController, mMockOptionalSplitScreen,
+ mMockDisplayController, mMockPipUiEventLogger,
mMockShellTaskOrganizer, mMainExecutor));
mMainExecutor.flushAll();
preparePipTaskOrg();
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index f6ad4c2f3aa5..ece150a4bd45 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -535,7 +535,10 @@ cc_defaults {
target: {
android: {
- header_libs: ["libandroid_headers_private"],
+ header_libs: [
+ "libandroid_headers_private",
+ "libtonemap_headers",
+ ],
srcs: [
"hwui/AnimatedImageThread.cpp",
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fd6e6e932ebc..055dbb2b5c5e 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -442,14 +442,13 @@ public:
reply.readExceptionCode();
}
- void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
+ void mountObb(const String16& rawPath, const String16& canonicalPath,
const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
{
Parcel data, reply;
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
data.writeString16(rawPath);
data.writeString16(canonicalPath);
- data.writeString16(key);
data.writeStrongBinder(IInterface::asBinder(token));
data.writeInt32(nonce);
obbInfo->writeToParcel(&data);
diff --git a/libs/storage/include/storage/IMountService.h b/libs/storage/include/storage/IMountService.h
index 2463e023efc1..5b07318f4432 100644
--- a/libs/storage/include/storage/IMountService.h
+++ b/libs/storage/include/storage/IMountService.h
@@ -64,8 +64,8 @@ public:
virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
virtual void finishMediaUpdate() = 0;
virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
- const String16& key, const sp<IObbActionListener>& token,
- const int32_t nonce, const sp<ObbInfo>& obbInfo) = 0;
+ const sp<IObbActionListener>& token, const int32_t nonce,
+ const sp<ObbInfo>& obbInfo) = 0;
virtual void unmountObb(const String16& filename, const bool force,
const sp<IObbActionListener>& token, const int32_t nonce) = 0;
virtual bool isObbMounted(const String16& filename) = 0;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3a2f0d9194f5..432196c9e4ef 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -8450,6 +8450,22 @@ public class AudioManager {
}
}
+ /**
+ * Returns the audio HAL version in the form MAJOR.MINOR. If there is no audio HAL found, null
+ * will be returned.
+ *
+ * @hide
+ */
+ @TestApi
+ public static @Nullable String getHalVersion() {
+ try {
+ return getService().getHalVersion();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error querying getHalVersion", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private final Object mMuteAwaitConnectionListenerLock = new Object();
@GuardedBy("mMuteAwaitConnectionListenerLock")
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fa3057a4ead1..bdbb740a849b 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -480,7 +480,6 @@ interface IAudioService {
boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb);
-
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
void addAssistantServicesUids(in int[] assistantUID);
@@ -501,4 +500,6 @@ interface IAudioService {
in IAudioDeviceVolumeDispatcher cb,
in String packageName,
in AudioDeviceAttributes device, in List<VolumeInfo> volumes);
+
+ String getHalVersion();
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 311476cbd489..47e402f73f40 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -76,6 +76,7 @@ public final class MediaRouter2 {
@GuardedBy("sSystemRouterLock")
private static Map<String, MediaRouter2> sSystemMediaRouter2Map = new ArrayMap<>();
+
private static MediaRouter2Manager sManager;
@GuardedBy("sRouterLock")
@@ -119,14 +120,12 @@ public final class MediaRouter2 {
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
final Handler mHandler;
- @GuardedBy("mLock")
- private boolean mShouldUpdateRoutes = true;
+
+ private volatile ArrayMap<String, MediaRoute2Info> mPreviousRoutes = new ArrayMap<>();
private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
- /**
- * Gets an instance of the media router associated with the context.
- */
+ /** Gets an instance of the media router associated with the context. */
@NonNull
public static MediaRouter2 getInstance(@NonNull Context context) {
Objects.requireNonNull(context, "context must not be null");
@@ -139,29 +138,31 @@ public final class MediaRouter2 {
}
/**
- * Gets an instance of the system media router which controls the app's media routing.
- * Returns {@code null} if the given package name is invalid.
- * There are several things to note when using the media routers created with this method.
- * <p>
- * First of all, the discovery preference passed to {@link #registerRouteCallback}
- * will have no effect. The callback will be called accordingly with the client app's
- * discovery preference. Therefore, it is recommended to pass
- * {@link RouteDiscoveryPreference#EMPTY} there.
- * <p>
- * Also, do not keep/compare the instances of the {@link RoutingController}, since they are
+ * Gets an instance of the system media router which controls the app's media routing. Returns
+ * {@code null} if the given package name is invalid. There are several things to note when
+ * using the media routers created with this method.
+ *
+ * <p>First of all, the discovery preference passed to {@link #registerRouteCallback} will have
+ * no effect. The callback will be called accordingly with the client app's discovery
+ * preference. Therefore, it is recommended to pass {@link RouteDiscoveryPreference#EMPTY}
+ * there.
+ *
+ * <p>Also, do not keep/compare the instances of the {@link RoutingController}, since they are
* always newly created with the latest session information whenever below methods are called:
+ *
* <ul>
- * <li> {@link #getControllers()} </li>
- * <li> {@link #getController(String)}} </li>
- * <li> {@link TransferCallback#onTransfer(RoutingController, RoutingController)} </li>
- * <li> {@link TransferCallback#onStop(RoutingController)} </li>
- * <li> {@link ControllerCallback#onControllerUpdated(RoutingController)} </li>
+ * <li>{@link #getControllers()}
+ * <li>{@link #getController(String)}}
+ * <li>{@link TransferCallback#onTransfer(RoutingController, RoutingController)}
+ * <li>{@link TransferCallback#onStop(RoutingController)}
+ * <li>{@link ControllerCallback#onControllerUpdated(RoutingController)}
* </ul>
+ *
* Therefore, in order to track the current routing status, keep the controller's ID instead,
- * and use {@link #getController(String)} and {@link #getSystemController()} for
- * getting controllers.
- * <p>
- * Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
+ * and use {@link #getController(String)} and {@link #getSystemController()} for getting
+ * controllers.
+ *
+ * <p>Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
*
* @param clientPackageName the package name of the app to control
* @throws SecurityException if the caller doesn't have MODIFY_AUDIO_ROUTING permission.
@@ -170,15 +171,16 @@ public final class MediaRouter2 {
@SystemApi
@RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
@Nullable
- public static MediaRouter2 getInstance(@NonNull Context context,
- @NonNull String clientPackageName) {
+ public static MediaRouter2 getInstance(
+ @NonNull Context context, @NonNull String clientPackageName) {
Objects.requireNonNull(context, "context must not be null");
Objects.requireNonNull(clientPackageName, "clientPackageName must not be null");
// Note: Even though this check could be somehow bypassed, the other permission checks
// in system server will not allow MediaRouter2Manager to be registered.
- IMediaRouterService serviceBinder = IMediaRouterService.Stub.asInterface(
- ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+ IMediaRouterService serviceBinder =
+ IMediaRouterService.Stub.asInterface(
+ ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
try {
// SecurityException will be thrown if there's no permission.
serviceBinder.enforceMediaContentControlPermission();
@@ -212,17 +214,17 @@ public final class MediaRouter2 {
/**
* Starts scanning remote routes.
- * <p>
- * Route discovery can happen even when the {@link #startScan()} is not called.
- * This is because the scanning could be started before by other apps.
- * Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
- * that the routes found before are removed and added again.
- * <p>
- * Use {@link RouteCallback} to get the route related events.
- * <p>
- * Note that calling start/stopScan is applied to all system routers in the same process.
- * <p>
- * This will be no-op for non-system media routers.
+ *
+ * <p>Route discovery can happen even when the {@link #startScan()} is not called. This is
+ * because the scanning could be started before by other apps. Therefore, calling this method
+ * after calling {@link #stopScan()} does not necessarily mean that the routes found before are
+ * removed and added again.
+ *
+ * <p>Use {@link RouteCallback} to get the route related events.
+ *
+ * <p>Note that calling start/stopScan is applied to all system routers in the same process.
+ *
+ * <p>This will be no-op for non-system media routers.
*
* @see #stopScan()
* @see #getInstance(Context, String)
@@ -238,18 +240,17 @@ public final class MediaRouter2 {
/**
* Stops scanning remote routes to reduce resource consumption.
- * <p>
- * Route discovery can be continued even after this method is called.
- * This is because the scanning is only turned off when all the apps stop scanning.
- * Therefore, calling this method does not necessarily mean the routes are removed.
- * Also, for the same reason it does not mean that {@link RouteCallback#onRoutesAdded(List)}
- * is not called afterwards.
- * <p>
- * Use {@link RouteCallback} to get the route related events.
- * <p>
- * Note that calling start/stopScan is applied to all system routers in the same process.
- * <p>
- * This will be no-op for non-system media routers.
+ *
+ * <p>Route discovery can be continued even after this method is called. This is because the
+ * scanning is only turned off when all the apps stop scanning. Therefore, calling this method
+ * does not necessarily mean the routes are removed. Also, for the same reason it does not mean
+ * that {@link RouteCallback#onRoutesAdded(List)} is not called afterwards.
+ *
+ * <p>Use {@link RouteCallback} to get the route related events.
+ *
+ * <p>Note that calling start/stopScan is applied to all system routers in the same process.
+ *
+ * <p>This will be no-op for non-system media routers.
*
* @see #startScan()
* @see #getInstance(Context, String)
@@ -265,8 +266,9 @@ public final class MediaRouter2 {
private MediaRouter2(Context appContext) {
mContext = appContext;
- mMediaRouterService = IMediaRouterService.Stub.asInterface(
- ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+ mMediaRouterService =
+ IMediaRouterService.Stub.asInterface(
+ ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
mPackageName = mContext.getPackageName();
mHandler = new Handler(Looper.getMainLooper());
@@ -302,9 +304,10 @@ public final class MediaRouter2 {
mClientPackageName = clientPackageName;
mManagerCallback = new ManagerCallback();
mHandler = new Handler(Looper.getMainLooper());
- mSystemController = new SystemRoutingController(
- ensureClientPackageNameForSystemSession(
- sManager.getSystemRoutingSession(clientPackageName)));
+ mSystemController =
+ new SystemRoutingController(
+ ensureClientPackageNameForSystemSession(
+ sManager.getSystemRoutingSession(clientPackageName)));
mDiscoveryPreference = sManager.getDiscoveryPreference(clientPackageName);
updateAllRoutesFromManager();
@@ -318,8 +321,8 @@ public final class MediaRouter2 {
*
* @hide
*/
- static boolean checkRouteListContainsRouteId(@NonNull List<MediaRoute2Info> routeList,
- @NonNull String routeId) {
+ static boolean checkRouteListContainsRouteId(
+ @NonNull List<MediaRoute2Info> routeList, @NonNull String routeId) {
for (MediaRoute2Info info : routeList) {
if (TextUtils.equals(routeId, info.getId())) {
return true;
@@ -330,8 +333,8 @@ public final class MediaRouter2 {
/**
* Gets the client package name of the app which this media router controls.
- * <p>
- * This will return null for non-system media routers.
+ *
+ * <p>This will return null for non-system media routers.
*
* @see #getInstance(Context, String)
* @hide
@@ -344,12 +347,12 @@ public final class MediaRouter2 {
/**
* Registers a callback to discover routes and to receive events when they change.
- * <p>
- * If the specified callback is already registered, its registration will be updated for the
+ *
+ * <p>If the specified callback is already registered, its registration will be updated for the
* given {@link Executor executor} and {@link RouteDiscoveryPreference discovery preference}.
- * </p>
*/
- public void registerRouteCallback(@NonNull @CallbackExecutor Executor executor,
+ public void registerRouteCallback(
+ @NonNull @CallbackExecutor Executor executor,
@NonNull RouteCallback routeCallback,
@NonNull RouteDiscoveryPreference preference) {
Objects.requireNonNull(executor, "executor must not be null");
@@ -391,8 +394,8 @@ public final class MediaRouter2 {
}
/**
- * Unregisters the given callback. The callback will no longer receive events.
- * If the callback has not been added or been removed already, it is ignored.
+ * Unregisters the given callback. The callback will no longer receive events. If the callback
+ * has not been added or been removed already, it is ignored.
*
* @param routeCallback the callback to unregister
* @see #registerRouteCallback
@@ -400,8 +403,7 @@ public final class MediaRouter2 {
public void unregisterRouteCallback(@NonNull RouteCallback routeCallback) {
Objects.requireNonNull(routeCallback, "callback must not be null");
- if (!mRouteCallbackRecords.remove(
- new RouteCallbackRecord(null, routeCallback, null))) {
+ if (!mRouteCallbackRecords.remove(new RouteCallbackRecord(null, routeCallback, null))) {
Log.w(TAG, "unregisterRouteCallback: Ignoring unknown callback");
return;
}
@@ -416,8 +418,7 @@ public final class MediaRouter2 {
}
if (updateDiscoveryPreferenceIfNeededLocked()) {
try {
- mMediaRouterService.setDiscoveryRequestWithRouter2(
- mStub, mDiscoveryPreference);
+ mMediaRouterService.setDiscoveryRequestWithRouter2(mStub, mDiscoveryPreference);
} catch (RemoteException ex) {
Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.", ex);
}
@@ -430,27 +431,28 @@ public final class MediaRouter2 {
}
mStub = null;
}
- mShouldUpdateRoutes = true;
}
}
+ @GuardedBy("mLock")
private boolean updateDiscoveryPreferenceIfNeededLocked() {
RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
mRouteCallbackRecords.stream().map(record -> record.mPreference).collect(
Collectors.toList())).build();
+
if (Objects.equals(mDiscoveryPreference, newDiscoveryPreference)) {
return false;
}
mDiscoveryPreference = newDiscoveryPreference;
- mShouldUpdateRoutes = true;
+ updateFilteredRoutesLocked();
return true;
}
/**
- * Gets the list of all discovered routes.
- * This list includes the routes that are not related to the client app.
- * <p>
- * This will return an empty list for non-system media routers.
+ * Gets the list of all discovered routes. This list includes the routes that are not related to
+ * the client app.
+ *
+ * <p>This will return an empty list for non-system media routers.
*
* @hide
*/
@@ -464,25 +466,19 @@ public final class MediaRouter2 {
}
/**
- * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
- * known to the media router.
- * <p>
- * Please note that the list can be changed before callbacks are invoked.
- * </p>
+ * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently known to the media
+ * router.
+ *
+ * <p>Please note that the list can be changed before callbacks are invoked.
+ *
* @return the list of routes that contains at least one of the route features in discovery
- * preferences registered by the application
+ * preferences registered by the application
*/
@NonNull
public List<MediaRoute2Info> getRoutes() {
synchronized (mLock) {
- if (mShouldUpdateRoutes) {
- mShouldUpdateRoutes = false;
-
- mFilteredRoutes = Collections.unmodifiableList(
- filterRoutes(List.copyOf(mRoutes.values()), mDiscoveryPreference));
- }
+ return mFilteredRoutes;
}
- return mFilteredRoutes;
}
/**
@@ -493,8 +489,8 @@ public final class MediaRouter2 {
* @param callback the callback to register
* @see #unregisterTransferCallback
*/
- public void registerTransferCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull TransferCallback callback) {
+ public void registerTransferCallback(
+ @NonNull @CallbackExecutor Executor executor, @NonNull TransferCallback callback) {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(callback, "callback must not be null");
@@ -522,12 +518,13 @@ public final class MediaRouter2 {
}
/**
- * Registers a {@link ControllerCallback}.
- * If you register the same callback twice or more, it will be ignored.
+ * Registers a {@link ControllerCallback}. If you register the same callback twice or more, it
+ * will be ignored.
+ *
* @see #unregisterControllerCallback(ControllerCallback)
*/
- public void registerControllerCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull ControllerCallback callback) {
+ public void registerControllerCallback(
+ @NonNull @CallbackExecutor Executor executor, @NonNull ControllerCallback callback) {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(callback, "callback must not be null");
@@ -539,12 +536,12 @@ public final class MediaRouter2 {
}
/**
- * Unregisters a {@link ControllerCallback}. The callback will no longer receive
- * events. If the callback has not been added or been removed already, it is ignored.
+ * Unregisters a {@link ControllerCallback}. The callback will no longer receive events.
+ * If the callback has not been added or been removed already, it is ignored.
+ *
* @see #registerControllerCallback(Executor, ControllerCallback)
*/
- public void unregisterControllerCallback(
- @NonNull ControllerCallback callback) {
+ public void unregisterControllerCallback(@NonNull ControllerCallback callback) {
Objects.requireNonNull(callback, "callback must not be null");
if (!mControllerCallbackRecords.remove(new ControllerCallbackRecord(null, callback))) {
@@ -559,7 +556,7 @@ public final class MediaRouter2 {
* {@link #transferTo(MediaRoute2Info)}.
*
* @param listener A listener to send optional app-specific hints when creating a controller.
- * {@code null} for unset.
+ * {@code null} for unset.
*/
public void setOnGetControllerHintsListener(@Nullable OnGetControllerHintsListener listener) {
if (isSystemRouter()) {
@@ -569,13 +566,11 @@ public final class MediaRouter2 {
}
/**
- * Transfers the current media to the given route.
- * If it's necessary a new {@link RoutingController} is created or it is handled within
- * the current routing controller.
+ * Transfers the current media to the given route. If it's necessary a new
+ * {@link RoutingController} is created or it is handled within the current routing controller.
*
* @param route the route you want to transfer the current media to. Pass {@code null} to
* stop routing of the current media.
- *
* @see TransferCallback#onTransfer
* @see TransferCallback#onTransferFailure
*/
@@ -622,8 +617,8 @@ public final class MediaRouter2 {
/**
* Transfers the media of a routing controller to the given route.
- * <p>
- * This will be no-op for non-system media routers.
+ *
+ * <p>This will be no-op for non-system media routers.
*
* @param controller a routing controller controlling media routing.
* @param route the route you want to transfer the media to.
@@ -638,13 +633,15 @@ public final class MediaRouter2 {
}
}
- void requestCreateController(@NonNull RoutingController controller,
- @NonNull MediaRoute2Info route, long managerRequestId) {
+ void requestCreateController(
+ @NonNull RoutingController controller,
+ @NonNull MediaRoute2Info route,
+ long managerRequestId) {
final int requestId = mNextRequestId.getAndIncrement();
- ControllerCreationRequest request = new ControllerCreationRequest(requestId,
- managerRequestId, route, controller);
+ ControllerCreationRequest request =
+ new ControllerCreationRequest(requestId, managerRequestId, route, controller);
mControllerCreationRequests.add(request);
OnGetControllerHintsListener listener = mOnGetControllerHintsListener;
@@ -663,11 +660,15 @@ public final class MediaRouter2 {
if (stub != null) {
try {
mMediaRouterService.requestCreateSessionWithRouter2(
- stub, requestId, managerRequestId,
- controller.getRoutingSessionInfo(), route, controllerHints);
+ stub,
+ requestId,
+ managerRequestId,
+ controller.getRoutingSessionInfo(),
+ route,
+ controllerHints);
} catch (RemoteException ex) {
Log.e(TAG, "createControllerForTransfer: "
- + "Failed to request for creating a controller.", ex);
+ + "Failed to request for creating a controller.", ex);
mControllerCreationRequests.remove(request);
if (managerRequestId == MANAGER_REQUEST_ID_NONE) {
notifyTransferFailure(route);
@@ -685,11 +686,11 @@ public final class MediaRouter2 {
/**
* Gets a {@link RoutingController} which can control the routes provided by system.
* e.g. Phone speaker, wired headset, Bluetooth, etc.
- * <p>
- * Note: The system controller can't be released. Calling {@link RoutingController#release()}
+ *
+ * <p>Note: The system controller can't be released. Calling {@link RoutingController#release()}
* will be ignored.
- * <p>
- * This method always returns the same instance.
+ *
+ * <p>This method always returns the same instance.
*/
@NonNull
public RoutingController getSystemController() {
@@ -714,8 +715,8 @@ public final class MediaRouter2 {
/**
* Gets the list of currently active {@link RoutingController routing controllers} on which
* media can be played.
- * <p>
- * Note: The list returned here will never be empty. The first element in the list is
+ *
+ * <p>Note: The list returned here will never be empty. The first element in the list is
* always the {@link #getSystemController() system controller}.
*/
@NonNull
@@ -750,8 +751,8 @@ public final class MediaRouter2 {
/**
* Requests a volume change for the route asynchronously.
* It may have no effect if the route is currently not selected.
- * <p>
- * This will be no-op for non-system media routers.
+ *
+ * <p>This will be no-op for non-system media routers.
*
* @param volume The new volume value between 0 and {@link MediaRoute2Info#getVolumeMax}.
* @see #getInstance(Context, String)
@@ -769,55 +770,61 @@ public final class MediaRouter2 {
// If this API needs to be public, use IMediaRouterService#setRouteVolumeWithRouter2()
}
- void syncRoutesOnHandler(List<MediaRoute2Info> currentRoutes,
- RoutingSessionInfo currentSystemSessionInfo) {
+ void syncRoutesOnHandler(
+ List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
Log.e(TAG, "syncRoutesOnHandler: Received wrong data. currentRoutes=" + currentRoutes
+ ", currentSystemSessionInfo=" + currentSystemSessionInfo);
return;
}
+ synchronized (mLock) {
+ mRoutes.clear();
+ for (MediaRoute2Info route : currentRoutes) {
+ mRoutes.put(route.getId(), route);
+ }
+ updateFilteredRoutesLocked();
+ }
+
+ RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
+ mSystemController.setRoutingSessionInfo(currentSystemSessionInfo);
+ if (!oldInfo.equals(currentSystemSessionInfo)) {
+ notifyControllerUpdated(mSystemController);
+ }
+ }
+
+ void dispatchFilteredRoutesChangedLocked(List<MediaRoute2Info> newRoutes) {
List<MediaRoute2Info> addedRoutes = new ArrayList<>();
List<MediaRoute2Info> removedRoutes = new ArrayList<>();
List<MediaRoute2Info> changedRoutes = new ArrayList<>();
- synchronized (mLock) {
- List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
- .collect(Collectors.toList());
-
- for (String routeId : mRoutes.keySet()) {
- if (!currentRoutesIds.contains(routeId)) {
- // This route is removed while the callback is unregistered.
- MediaRoute2Info route = mRoutes.get(routeId);
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
- removedRoutes.add(mRoutes.get(routeId));
- }
- }
- }
+ Set<String> newRouteIds =
+ newRoutes.stream().map(MediaRoute2Info::getId).collect(Collectors.toSet());
- for (MediaRoute2Info route : currentRoutes) {
- if (mRoutes.containsKey(route.getId())) {
- if (!route.equals(mRoutes.get(route.getId()))) {
- // This route is changed while the callback is unregistered.
- if (route.hasAnyFeatures(
- mDiscoveryPreference.getPreferredFeatures())) {
- changedRoutes.add(route);
- }
- }
- } else {
- // This route is added while the callback is unregistered.
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
- addedRoutes.add(route);
- }
- }
+ for (MediaRoute2Info route : newRoutes) {
+ MediaRoute2Info prevRoute = mPreviousRoutes.get(route.getId());
+ if (prevRoute == null) {
+ addedRoutes.add(route);
+ } else if (!prevRoute.equals(route)) {
+ changedRoutes.add(route);
}
+ }
- mRoutes.clear();
- for (MediaRoute2Info route : currentRoutes) {
- mRoutes.put(route.getId(), route);
+ for (int i = 0; i < mPreviousRoutes.size(); i++) {
+ if (!newRouteIds.contains(mPreviousRoutes.keyAt(i))) {
+ removedRoutes.add(mPreviousRoutes.valueAt(i));
}
+ }
- mShouldUpdateRoutes = true;
+ // update previous routes
+ for (MediaRoute2Info route : removedRoutes) {
+ mPreviousRoutes.remove(route.getId());
+ }
+ for (MediaRoute2Info route : addedRoutes) {
+ mPreviousRoutes.put(route.getId(), route);
+ }
+ for (MediaRoute2Info route : changedRoutes) {
+ mPreviousRoutes.put(route.getId(), route);
}
if (!addedRoutes.isEmpty()) {
@@ -829,43 +836,23 @@ public final class MediaRouter2 {
if (!changedRoutes.isEmpty()) {
notifyRoutesChanged(changedRoutes);
}
-
- RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
- mSystemController.setRoutingSessionInfo(currentSystemSessionInfo);
- if (!oldInfo.equals(currentSystemSessionInfo)) {
- notifyControllerUpdated(mSystemController);
- }
}
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
- List<MediaRoute2Info> addedRoutes = new ArrayList<>();
synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
- addedRoutes.add(route);
- }
}
- mShouldUpdateRoutes = true;
- }
- if (!addedRoutes.isEmpty()) {
- notifyRoutesAdded(addedRoutes);
+ updateFilteredRoutesLocked();
}
}
void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
- List<MediaRoute2Info> removedRoutes = new ArrayList<>();
synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.remove(route.getId());
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
- removedRoutes.add(route);
- }
}
- mShouldUpdateRoutes = true;
- }
- if (!removedRoutes.isEmpty()) {
- notifyRoutesRemoved(removedRoutes);
+ updateFilteredRoutesLocked();
}
}
@@ -874,23 +861,27 @@ public final class MediaRouter2 {
synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
- changedRoutes.add(route);
- }
}
- mShouldUpdateRoutes = true;
- }
- if (!changedRoutes.isEmpty()) {
- notifyRoutesChanged(changedRoutes);
+ updateFilteredRoutesLocked();
}
}
+ /** Updates filtered routes and dispatch callbacks */
+ @GuardedBy("mLock")
+ void updateFilteredRoutesLocked() {
+ mFilteredRoutes =
+ Collections.unmodifiableList(
+ filterRoutesWithCompositePreferenceLocked(List.copyOf(mRoutes.values())));
+ mHandler.sendMessage(
+ obtainMessage(MediaRouter2::dispatchFilteredRoutesChangedLocked,
+ this, mFilteredRoutes));
+ }
+
/**
- * Creates a controller and calls the {@link TransferCallback#onTransfer}.
- * If the controller creation has failed, then it calls
- * {@link TransferCallback#onTransferFailure}.
- * <p>
- * Pass {@code null} to sessionInfo for the failure case.
+ * Creates a controller and calls the {@link TransferCallback#onTransfer}. If the controller
+ * creation has failed, then it calls {@link TransferCallback#onTransferFailure}.
+ *
+ * <p>Pass {@code null} to sessionInfo for the failure case.
*/
void createControllerOnHandler(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
ControllerCreationRequest matchingRequest = null;
@@ -913,12 +904,15 @@ public final class MediaRouter2 {
if (sessionInfo == null) {
notifyTransferFailure(requestedRoute);
return;
- } else if (!TextUtils.equals(requestedRoute.getProviderId(),
- sessionInfo.getProviderId())) {
- Log.w(TAG, "The session's provider ID does not match the requested route's. "
- + "(requested route's providerId=" + requestedRoute.getProviderId()
- + ", actual providerId=" + sessionInfo.getProviderId()
- + ")");
+ } else if (!TextUtils.equals(requestedRoute.getProviderId(), sessionInfo.getProviderId())) {
+ Log.w(
+ TAG,
+ "The session's provider ID does not match the requested route's. "
+ + "(requested route's providerId="
+ + requestedRoute.getProviderId()
+ + ", actual providerId="
+ + sessionInfo.getProviderId()
+ + ")");
notifyTransferFailure(requestedRoute);
return;
}
@@ -927,9 +921,12 @@ public final class MediaRouter2 {
// When the old controller is released before transferred, treat it as a failure.
// This could also happen when transfer is requested twice or more.
if (!oldController.scheduleRelease()) {
- Log.w(TAG, "createControllerOnHandler: "
- + "Ignoring controller creation for released old controller. "
- + "oldController=" + oldController);
+ Log.w(
+ TAG,
+ "createControllerOnHandler: "
+ + "Ignoring controller creation for released old controller. "
+ + "oldController="
+ + oldController);
if (!sessionInfo.isSystemSession()) {
new RoutingController(sessionInfo).release();
}
@@ -971,15 +968,21 @@ public final class MediaRouter2 {
}
if (matchingController == null) {
- Log.w(TAG, "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
- + sessionInfo.getId());
+ Log.w(
+ TAG,
+ "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
+ + sessionInfo.getId());
return;
}
RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
- Log.w(TAG, "updateControllerOnHandler: Provider IDs are not matched. old="
- + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+ Log.w(
+ TAG,
+ "updateControllerOnHandler: Provider IDs are not matched. old="
+ + oldInfo.getProviderId()
+ + ", new="
+ + sessionInfo.getProviderId());
return;
}
@@ -1000,24 +1003,31 @@ public final class MediaRouter2 {
if (matchingController == null) {
if (DEBUG) {
- Log.d(TAG, "releaseControllerOnHandler: Matching controller not found. "
- + "uniqueSessionId=" + sessionInfo.getId());
+ Log.d(
+ TAG,
+ "releaseControllerOnHandler: Matching controller not found. "
+ + "uniqueSessionId="
+ + sessionInfo.getId());
}
return;
}
RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
- Log.w(TAG, "releaseControllerOnHandler: Provider IDs are not matched. old="
- + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+ Log.w(
+ TAG,
+ "releaseControllerOnHandler: Provider IDs are not matched. old="
+ + oldInfo.getProviderId()
+ + ", new="
+ + sessionInfo.getProviderId());
return;
}
matchingController.releaseInternal(/* shouldReleaseSession= */ false);
}
- void onRequestCreateControllerByManagerOnHandler(RoutingSessionInfo oldSession,
- MediaRoute2Info route, long managerRequestId) {
+ void onRequestCreateControllerByManagerOnHandler(
+ RoutingSessionInfo oldSession, MediaRoute2Info route, long managerRequestId) {
RoutingController controller;
if (oldSession.isSystemSession()) {
controller = getSystemController();
@@ -1033,17 +1043,17 @@ public final class MediaRouter2 {
}
/**
- * Returns whether this router is created with {@link #getInstance(Context, String)}.
- * This kind of router can control the target app's media routing.
+ * Returns whether this router is created with {@link #getInstance(Context, String)}. This kind
+ * of router can control the target app's media routing.
*/
private boolean isSystemRouter() {
return mClientPackageName != null;
}
/**
- * Returns a {@link RoutingSessionInfo} which has the client package name.
- * The client package name is set only when the given sessionInfo doesn't have it.
- * Should only used for system media routers.
+ * Returns a {@link RoutingSessionInfo} which has the client package name. The client package
+ * name is set only when the given sessionInfo doesn't have it. Should only used for system
+ * media routers.
*/
private RoutingSessionInfo ensureClientPackageNameForSystemSession(
@NonNull RoutingSessionInfo sessionInfo) {
@@ -1057,41 +1067,44 @@ public final class MediaRouter2 {
.build();
}
- private List<MediaRoute2Info> getSortedRoutes(List<MediaRoute2Info> routes,
- RouteDiscoveryPreference preference) {
- if (!preference.shouldRemoveDuplicates()) {
+ private List<MediaRoute2Info> getSortedRoutes(
+ List<MediaRoute2Info> routes, List<String> packageOrder) {
+ if (packageOrder.isEmpty()) {
return routes;
}
Map<String, Integer> packagePriority = new ArrayMap<>();
- int count = preference.getDeduplicationPackageOrder().size();
+ int count = packageOrder.size();
for (int i = 0; i < count; i++) {
// the last package will have 1 as the priority
- packagePriority.put(preference.getDeduplicationPackageOrder().get(i), count - i);
+ packagePriority.put(packageOrder.get(i), count - i);
}
ArrayList<MediaRoute2Info> sortedRoutes = new ArrayList<>(routes);
// take the negative for descending order
- sortedRoutes.sort(Comparator.comparingInt(
- r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
+ sortedRoutes.sort(
+ Comparator.comparingInt(r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
return sortedRoutes;
}
- private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
- RouteDiscoveryPreference discoveryPreference) {
+ @GuardedBy("mLock")
+ private List<MediaRoute2Info> filterRoutesWithCompositePreferenceLocked(
+ List<MediaRoute2Info> routes) {
Set<String> deduplicationIdSet = new ArraySet<>();
List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
- for (MediaRoute2Info route : getSortedRoutes(routes, discoveryPreference)) {
- if (!route.hasAnyFeatures(discoveryPreference.getPreferredFeatures())) {
+ for (MediaRoute2Info route :
+ getSortedRoutes(routes, mDiscoveryPreference.getDeduplicationPackageOrder())) {
+ if (!route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
continue;
}
- if (!discoveryPreference.getAllowedPackages().isEmpty()
+ if (!mDiscoveryPreference.getAllowedPackages().isEmpty()
&& (route.getPackageName() == null
- || !discoveryPreference.getAllowedPackages()
- .contains(route.getPackageName()))) {
+ || !mDiscoveryPreference
+ .getAllowedPackages()
+ .contains(route.getPackageName()))) {
continue;
}
- if (discoveryPreference.shouldRemoveDuplicates()) {
+ if (mDiscoveryPreference.shouldRemoveDuplicates()) {
if (!Collections.disjoint(deduplicationIdSet, route.getDeduplicationIds())) {
continue;
}
@@ -1102,6 +1115,25 @@ public final class MediaRouter2 {
return filteredRoutes;
}
+ private List<MediaRoute2Info> filterRoutesWithIndividualPreference(
+ List<MediaRoute2Info> routes, RouteDiscoveryPreference discoveryPreference) {
+ List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
+ for (MediaRoute2Info route : routes) {
+ if (!route.hasAnyFeatures(discoveryPreference.getPreferredFeatures())) {
+ continue;
+ }
+ if (!discoveryPreference.getAllowedPackages().isEmpty()
+ && (route.getPackageName() == null
+ || !discoveryPreference
+ .getAllowedPackages()
+ .contains(route.getPackageName()))) {
+ continue;
+ }
+ filteredRoutes.add(route);
+ }
+ return filteredRoutes;
+ }
+
private void updateAllRoutesFromManager() {
if (!isSystemRouter()) {
return;
@@ -1111,23 +1143,24 @@ public final class MediaRouter2 {
for (MediaRoute2Info route : sManager.getAllRoutes()) {
mRoutes.put(route.getId(), route);
}
- mShouldUpdateRoutes = true;
+ updateFilteredRoutesLocked();
}
}
private void notifyRoutesAdded(List<MediaRoute2Info> routes) {
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+ for (RouteCallbackRecord record : mRouteCallbackRecords) {
+ List<MediaRoute2Info> filteredRoutes =
+ filterRoutesWithIndividualPreference(routes, record.mPreference);
if (!filteredRoutes.isEmpty()) {
- record.mExecutor.execute(
- () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+ record.mExecutor.execute(() -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
}
}
}
private void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+ for (RouteCallbackRecord record : mRouteCallbackRecords) {
+ List<MediaRoute2Info> filteredRoutes =
+ filterRoutesWithIndividualPreference(routes, record.mPreference);
if (!filteredRoutes.isEmpty()) {
record.mExecutor.execute(
() -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
@@ -1136,8 +1169,9 @@ public final class MediaRouter2 {
}
private void notifyRoutesChanged(List<MediaRoute2Info> routes) {
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+ for (RouteCallbackRecord record : mRouteCallbackRecords) {
+ List<MediaRoute2Info> filteredRoutes =
+ filterRoutesWithIndividualPreference(routes, record.mPreference);
if (!filteredRoutes.isEmpty()) {
record.mExecutor.execute(
() -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
@@ -1146,46 +1180,42 @@ public final class MediaRouter2 {
}
private void notifyPreferredFeaturesChanged(List<String> features) {
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ for (RouteCallbackRecord record : mRouteCallbackRecords) {
record.mExecutor.execute(
() -> record.mRouteCallback.onPreferredFeaturesChanged(features));
}
}
private void notifyTransfer(RoutingController oldController, RoutingController newController) {
- for (TransferCallbackRecord record: mTransferCallbackRecords) {
+ for (TransferCallbackRecord record : mTransferCallbackRecords) {
record.mExecutor.execute(
() -> record.mTransferCallback.onTransfer(oldController, newController));
}
}
private void notifyTransferFailure(MediaRoute2Info route) {
- for (TransferCallbackRecord record: mTransferCallbackRecords) {
- record.mExecutor.execute(
- () -> record.mTransferCallback.onTransferFailure(route));
+ for (TransferCallbackRecord record : mTransferCallbackRecords) {
+ record.mExecutor.execute(() -> record.mTransferCallback.onTransferFailure(route));
}
}
private void notifyStop(RoutingController controller) {
- for (TransferCallbackRecord record: mTransferCallbackRecords) {
- record.mExecutor.execute(
- () -> record.mTransferCallback.onStop(controller));
+ for (TransferCallbackRecord record : mTransferCallbackRecords) {
+ record.mExecutor.execute(() -> record.mTransferCallback.onStop(controller));
}
}
private void notifyControllerUpdated(RoutingController controller) {
- for (ControllerCallbackRecord record: mControllerCallbackRecords) {
+ for (ControllerCallbackRecord record : mControllerCallbackRecords) {
record.mExecutor.execute(() -> record.mCallback.onControllerUpdated(controller));
}
}
- /**
- * Callback for receiving events about media route discovery.
- */
+ /** Callback for receiving events about media route discovery. */
public abstract static class RouteCallback {
/**
- * Called when routes are added. Whenever you registers a callback, this will
- * be invoked with known routes.
+ * Called when routes are added. Whenever you registers a callback, this will be invoked
+ * with known routes.
*
* @param routes the list of routes that have been added. It's never empty.
*/
@@ -1199,17 +1229,17 @@ public final class MediaRouter2 {
public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
/**
- * Called when routes are changed. For example, it is called when the route's name
- * or volume have been changed.
+ * Called when routes are changed. For example, it is called when the route's name or volume
+ * have been changed.
*
* @param routes the list of routes that have been changed. It's never empty.
*/
public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
/**
- * Called when the client app's preferred features are changed.
- * When this is called, it is recommended to {@link #getRoutes()} to get the routes
- * that are currently available to the app.
+ * Called when the client app's preferred features are changed. When this is called, it is
+ * recommended to {@link #getRoutes()} to get the routes that are currently available to the
+ * app.
*
* @param preferredFeatures the new preferred features set by the application
* @hide
@@ -1218,26 +1248,25 @@ public final class MediaRouter2 {
public void onPreferredFeaturesChanged(@NonNull List<String> preferredFeatures) {}
}
- /**
- * Callback for receiving events on media transfer.
- */
+ /** Callback for receiving events on media transfer. */
public abstract static class TransferCallback {
/**
- * Called when a media is transferred between two different routing controllers.
- * This can happen by calling {@link #transferTo(MediaRoute2Info)}.
- * <p> Override this to start playback with {@code newController}. You may want to get
- * the status of the media that is being played with {@code oldController} and resume it
- * continuously with {@code newController}.
- * After this is called, any callbacks with {@code oldController} will not be invoked
- * unless {@code oldController} is the {@link #getSystemController() system controller}.
- * You need to {@link RoutingController#release() release} {@code oldController} before
- * playing the media with {@code newController}.
+ * Called when a media is transferred between two different routing controllers. This can
+ * happen by calling {@link #transferTo(MediaRoute2Info)}.
+ *
+ * <p>Override this to start playback with {@code newController}. You may want to get the
+ * status of the media that is being played with {@code oldController} and resume it
+ * continuously with {@code newController}. After this is called, any callbacks with {@code
+ * oldController} will not be invoked unless {@code oldController} is the {@link
+ * #getSystemController() system controller}. You need to {@link RoutingController#release()
+ * release} {@code oldController} before playing the media with {@code newController}.
*
* @param oldController the previous controller that controlled routing
* @param newController the new controller to control routing
* @see #transferTo(MediaRoute2Info)
*/
- public void onTransfer(@NonNull RoutingController oldController,
+ public void onTransfer(
+ @NonNull RoutingController oldController,
@NonNull RoutingController newController) {}
/**
@@ -1248,61 +1277,58 @@ public final class MediaRouter2 {
public void onTransferFailure(@NonNull MediaRoute2Info requestedRoute) {}
/**
- * Called when a media routing stops. It can be stopped by a user or a provider.
- * App should not continue playing media locally when this method is called.
- * The {@code controller} is released before this method is called.
+ * Called when a media routing stops. It can be stopped by a user or a provider. App should
+ * not continue playing media locally when this method is called. The {@code controller} is
+ * released before this method is called.
*
* @param controller the controller that controlled the stopped media routing
*/
- public void onStop(@NonNull RoutingController controller) { }
+ public void onStop(@NonNull RoutingController controller) {}
}
/**
- * A listener interface to send optional app-specific hints when creating a
- * {@link RoutingController}.
+ * A listener interface to send optional app-specific hints when creating a {@link
+ * RoutingController}.
*/
public interface OnGetControllerHintsListener {
/**
- * Called when the {@link MediaRouter2} or the system is about to request
- * a media route provider service to create a controller with the given route.
- * The {@link Bundle} returned here will be sent to media route provider service as a hint.
- * <p>
- * Since controller creation can be requested by the {@link MediaRouter2} and the system,
- * set the listener as soon as possible after acquiring {@link MediaRouter2} instance.
- * The method will be called on the same thread that calls
- * {@link #transferTo(MediaRoute2Info)} or the main thread if it is requested by the system.
+ * Called when the {@link MediaRouter2} or the system is about to request a media route
+ * provider service to create a controller with the given route. The {@link Bundle} returned
+ * here will be sent to media route provider service as a hint.
+ *
+ * <p>Since controller creation can be requested by the {@link MediaRouter2} and the system,
+ * set the listener as soon as possible after acquiring {@link MediaRouter2} instance. The
+ * method will be called on the same thread that calls {@link #transferTo(MediaRoute2Info)}
+ * or the main thread if it is requested by the system.
*
* @param route the route to create a controller with
- * @return An optional bundle of app-specific arguments to send to the provider,
- * or {@code null} if none. The contents of this bundle may affect the result of
- * controller creation.
+ * @return An optional bundle of app-specific arguments to send to the provider, or {@code
+ * null} if none. The contents of this bundle may affect the result of controller
+ * creation.
* @see MediaRoute2ProviderService#onCreateSession(long, String, String, Bundle)
*/
@Nullable
Bundle onGetControllerHints(@NonNull MediaRoute2Info route);
}
- /**
- * Callback for receiving {@link RoutingController} updates.
- */
+ /** Callback for receiving {@link RoutingController} updates. */
public abstract static class ControllerCallback {
/**
- * Called when a controller is updated. (e.g., when the selected routes of the
- * controller is changed or when the volume of the controller is changed.)
+ * Called when a controller is updated. (e.g., when the selected routes of the controller is
+ * changed or when the volume of the controller is changed.)
*
- * @param controller the updated controller. It may be the
- * {@link #getSystemController() system controller}.
+ * @param controller the updated controller. It may be the {@link #getSystemController()
+ * system controller}.
* @see #getSystemController()
*/
- public void onControllerUpdated(@NonNull RoutingController controller) { }
+ public void onControllerUpdated(@NonNull RoutingController controller) {}
}
/**
- * A class to control media routing session in media route provider.
- * For example, selecting/deselecting/transferring to routes of a session can be done through
- * this. Instances are created when
- * {@link TransferCallback#onTransfer(RoutingController, RoutingController)} is called,
- * which is invoked after {@link #transferTo(MediaRoute2Info)} is called.
+ * A class to control media routing session in media route provider. For example,
+ * selecting/deselecting/transferring to routes of a session can be done through this. Instances
+ * are created when {@link TransferCallback#onTransfer(RoutingController, RoutingController)} is
+ * called, which is invoked after {@link #transferTo(MediaRoute2Info)} is called.
*/
public class RoutingController {
private final Object mControllerLock = new Object();
@@ -1339,8 +1365,8 @@ public final class MediaRouter2 {
}
/**
- * Gets the original session ID set by
- * {@link RoutingSessionInfo.Builder#Builder(String, String)}.
+ * Gets the original session ID set by {@link RoutingSessionInfo.Builder#Builder(String,
+ * String)}.
*
* @hide
*/
@@ -1353,8 +1379,8 @@ public final class MediaRouter2 {
}
/**
- * Gets the control hints used to control routing session if available.
- * It is set by the media route provider.
+ * Gets the control hints used to control routing session if available. It is set by the
+ * media route provider.
*/
@Nullable
public Bundle getControlHints() {
@@ -1401,11 +1427,12 @@ public final class MediaRouter2 {
/**
* Gets the information about how volume is handled on the session.
- * <p>Please note that you may not control the volume of the session even when
- * you can control the volume of each selected route in the session.
*
- * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or
- * {@link MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}
+ * <p>Please note that you may not control the volume of the session even when you can
+ * control the volume of each selected route in the session.
+ *
+ * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or {@link
+ * MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}
*/
@MediaRoute2Info.PlaybackVolume
public int getVolumeHandling() {
@@ -1414,9 +1441,7 @@ public final class MediaRouter2 {
}
}
- /**
- * Gets the maximum volume of the session.
- */
+ /** Gets the maximum volume of the session. */
public int getVolumeMax() {
synchronized (mControllerLock) {
return mSessionInfo.getVolumeMax();
@@ -1425,11 +1450,10 @@ public final class MediaRouter2 {
/**
* Gets the current volume of the session.
- * <p>
- * When it's available, it represents the volume of routing session, which is a group
- * of selected routes. Use {@link MediaRoute2Info#getVolume()}
- * to get the volume of a route,
- * </p>
+ *
+ * <p>When it's available, it represents the volume of routing session, which is a group of
+ * selected routes. Use {@link MediaRoute2Info#getVolume()} to get the volume of a route,
+ *
* @see MediaRoute2Info#getVolume()
*/
public int getVolume() {
@@ -1439,9 +1463,9 @@ public final class MediaRouter2 {
}
/**
- * Returns true if this controller is released, false otherwise.
- * If it is released, then all other getters from this instance may return invalid values.
- * Also, any operations to this instance will be ignored once released.
+ * Returns true if this controller is released, false otherwise. If it is released, then all
+ * other getters from this instance may return invalid values. Also, any operations to this
+ * instance will be ignored once released.
*
* @see #release
*/
@@ -1454,14 +1478,16 @@ public final class MediaRouter2 {
/**
* Selects a route for the remote session. After a route is selected, the media is expected
* to be played to the all the selected routes. This is different from {@link
- * MediaRouter2#transferTo(MediaRoute2Info)} transferring to a route},
- * where the media is expected to 'move' from one route to another.
- * <p>
- * The given route must satisfy all of the following conditions:
+ * MediaRouter2#transferTo(MediaRoute2Info)} transferring to a route}, where the media is
+ * expected to 'move' from one route to another.
+ *
+ * <p>The given route must satisfy all of the following conditions:
+ *
* <ul>
- * <li>It should not be included in {@link #getSelectedRoutes()}</li>
- * <li>It should be included in {@link #getSelectableRoutes()}</li>
+ * <li>It should not be included in {@link #getSelectedRoutes()}
+ * <li>It should be included in {@link #getSelectableRoutes()}
* </ul>
+ *
* If the route doesn't meet any of above conditions, it will be ignored.
*
* @see #deselectRoute(MediaRoute2Info)
@@ -1509,12 +1535,14 @@ public final class MediaRouter2 {
/**
* Deselects a route from the remote session. After a route is deselected, the media is
* expected to be stopped on the deselected route.
- * <p>
- * The given route must satisfy all of the following conditions:
+ *
+ * <p>The given route must satisfy all of the following conditions:
+ *
* <ul>
- * <li>It should be included in {@link #getSelectedRoutes()}</li>
- * <li>It should be included in {@link #getDeselectableRoutes()}</li>
+ * <li>It should be included in {@link #getSelectedRoutes()}
+ * <li>It should be included in {@link #getDeselectableRoutes()}
* </ul>
+ *
* If the route doesn't meet any of above conditions, it will be ignored.
*
* @see #getSelectedRoutes()
@@ -1559,8 +1587,8 @@ public final class MediaRouter2 {
}
/**
- * Transfers to a given route for the remote session. The given route must be included
- * in {@link RoutingSessionInfo#getTransferableRoutes()}.
+ * Transfers to a given route for the remote session. The given route must be included in
+ * {@link RoutingSessionInfo#getTransferableRoutes()}.
*
* @see RoutingSessionInfo#getSelectedRoutes()
* @see RoutingSessionInfo#getTransferableRoutes()
@@ -1597,7 +1625,7 @@ public final class MediaRouter2 {
* Requests a volume change for the remote session asynchronously.
*
* @param volume The new volume value between 0 and {@link RoutingController#getVolumeMax}
- * (inclusive).
+ * (inclusive).
* @see #getVolume()
*/
public void setVolume(int volume) {
@@ -1634,9 +1662,9 @@ public final class MediaRouter2 {
}
/**
- * Releases this controller and the corresponding session.
- * Any operations on this controller after calling this method will be ignored.
- * The devices that are playing media will stop playing it.
+ * Releases this controller and the corresponding session. Any operations on this controller
+ * after calling this method will be ignored. The devices that are playing media will stop
+ * playing it.
*/
public void release() {
releaseInternal(/* shouldReleaseSession= */ true);
@@ -1644,8 +1672,9 @@ public final class MediaRouter2 {
/**
* Schedules release of the controller.
+ *
* @return {@code true} if it's successfully scheduled, {@code false} if it's already
- * scheduled to be released or released.
+ * scheduled to be released or released.
*/
boolean scheduleRelease() {
synchronized (mControllerLock) {
@@ -1701,11 +1730,15 @@ public final class MediaRouter2 {
}
if (shouldNotifyStop) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
- RoutingController.this));
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::notifyStop,
+ MediaRouter2.this,
+ RoutingController.this));
}
- if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()
+ if (mRouteCallbackRecords.isEmpty()
+ && mNonSystemRoutingControllers.isEmpty()
&& mStub != null) {
try {
mMediaRouterService.unregisterRouter2(mStub);
@@ -1720,26 +1753,34 @@ public final class MediaRouter2 {
@Override
public String toString() {
// To prevent logging spam, we only print the ID of each route.
- List<String> selectedRoutes = getSelectedRoutes().stream()
- .map(MediaRoute2Info::getId).collect(Collectors.toList());
- List<String> selectableRoutes = getSelectableRoutes().stream()
- .map(MediaRoute2Info::getId).collect(Collectors.toList());
- List<String> deselectableRoutes = getDeselectableRoutes().stream()
- .map(MediaRoute2Info::getId).collect(Collectors.toList());
-
- StringBuilder result = new StringBuilder()
- .append("RoutingController{ ")
- .append("id=").append(getId())
- .append(", selectedRoutes={")
- .append(selectedRoutes)
- .append("}")
- .append(", selectableRoutes={")
- .append(selectableRoutes)
- .append("}")
- .append(", deselectableRoutes={")
- .append(deselectableRoutes)
- .append("}")
- .append(" }");
+ List<String> selectedRoutes =
+ getSelectedRoutes().stream()
+ .map(MediaRoute2Info::getId)
+ .collect(Collectors.toList());
+ List<String> selectableRoutes =
+ getSelectableRoutes().stream()
+ .map(MediaRoute2Info::getId)
+ .collect(Collectors.toList());
+ List<String> deselectableRoutes =
+ getDeselectableRoutes().stream()
+ .map(MediaRoute2Info::getId)
+ .collect(Collectors.toList());
+
+ StringBuilder result =
+ new StringBuilder()
+ .append("RoutingController{ ")
+ .append("id=")
+ .append(getId())
+ .append(", selectedRoutes={")
+ .append(selectedRoutes)
+ .append("}")
+ .append(", selectableRoutes={")
+ .append(selectableRoutes)
+ .append("}")
+ .append(", deselectableRoutes={")
+ .append(deselectableRoutes)
+ .append("}")
+ .append(" }");
return result.toString();
}
@@ -1764,7 +1805,8 @@ public final class MediaRouter2 {
}
synchronized (mLock) {
- return routeIds.stream().map(mRoutes::get)
+ return routeIds.stream()
+ .map(mRoutes::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@@ -1799,7 +1841,9 @@ public final class MediaRouter2 {
public final RouteCallback mRouteCallback;
public final RouteDiscoveryPreference mPreference;
- RouteCallbackRecord(@Nullable Executor executor, @NonNull RouteCallback routeCallback,
+ RouteCallbackRecord(
+ @Nullable Executor executor,
+ @NonNull RouteCallback routeCallback,
@Nullable RouteDiscoveryPreference preference) {
mRouteCallback = routeCallback;
mExecutor = executor;
@@ -1827,8 +1871,8 @@ public final class MediaRouter2 {
public final Executor mExecutor;
public final TransferCallback mTransferCallback;
- TransferCallbackRecord(@NonNull Executor executor,
- @NonNull TransferCallback transferCallback) {
+ TransferCallbackRecord(
+ @NonNull Executor executor, @NonNull TransferCallback transferCallback) {
mTransferCallback = transferCallback;
mExecutor = executor;
}
@@ -1854,8 +1898,8 @@ public final class MediaRouter2 {
public final Executor mExecutor;
public final ControllerCallback mCallback;
- ControllerCallbackRecord(@Nullable Executor executor,
- @NonNull ControllerCallback callback) {
+ ControllerCallbackRecord(
+ @Nullable Executor executor, @NonNull ControllerCallback callback) {
mCallback = callback;
mExecutor = executor;
}
@@ -1883,66 +1927,87 @@ public final class MediaRouter2 {
public final MediaRoute2Info mRoute;
public final RoutingController mOldController;
- ControllerCreationRequest(int requestId, long managerRequestId,
- @NonNull MediaRoute2Info route, @NonNull RoutingController oldController) {
+ ControllerCreationRequest(
+ int requestId,
+ long managerRequestId,
+ @NonNull MediaRoute2Info route,
+ @NonNull RoutingController oldController) {
mRequestId = requestId;
mManagerRequestId = managerRequestId;
mRoute = Objects.requireNonNull(route, "route must not be null");
- mOldController = Objects.requireNonNull(oldController,
- "oldController must not be null");
+ mOldController =
+ Objects.requireNonNull(oldController, "oldController must not be null");
}
}
class MediaRouter2Stub extends IMediaRouter2.Stub {
@Override
- public void notifyRouterRegistered(List<MediaRoute2Info> currentRoutes,
- RoutingSessionInfo currentSystemSessionInfo) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::syncRoutesOnHandler,
- MediaRouter2.this, currentRoutes, currentSystemSessionInfo));
+ public void notifyRouterRegistered(
+ List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::syncRoutesOnHandler,
+ MediaRouter2.this,
+ currentRoutes,
+ currentSystemSessionInfo));
}
@Override
public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::addRoutesOnHandler,
- MediaRouter2.this, routes));
+ mHandler.sendMessage(
+ obtainMessage(MediaRouter2::addRoutesOnHandler, MediaRouter2.this, routes));
}
@Override
public void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::removeRoutesOnHandler,
- MediaRouter2.this, routes));
+ mHandler.sendMessage(
+ obtainMessage(MediaRouter2::removeRoutesOnHandler, MediaRouter2.this, routes));
}
@Override
public void notifyRoutesChanged(List<MediaRoute2Info> routes) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::changeRoutesOnHandler,
- MediaRouter2.this, routes));
+ mHandler.sendMessage(
+ obtainMessage(MediaRouter2::changeRoutesOnHandler, MediaRouter2.this, routes));
}
@Override
public void notifySessionCreated(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
- MediaRouter2.this, requestId, sessionInfo));
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::createControllerOnHandler,
+ MediaRouter2.this,
+ requestId,
+ sessionInfo));
}
@Override
public void notifySessionInfoChanged(@Nullable RoutingSessionInfo sessionInfo) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::updateControllerOnHandler,
- MediaRouter2.this, sessionInfo));
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::updateControllerOnHandler,
+ MediaRouter2.this,
+ sessionInfo));
}
@Override
public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::releaseControllerOnHandler,
- MediaRouter2.this, sessionInfo));
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::releaseControllerOnHandler,
+ MediaRouter2.this,
+ sessionInfo));
}
@Override
- public void requestCreateSessionByManager(long managerRequestId,
- RoutingSessionInfo oldSession, MediaRoute2Info route) {
- mHandler.sendMessage(obtainMessage(
- MediaRouter2::onRequestCreateControllerByManagerOnHandler,
- MediaRouter2.this, oldSession, route, managerRequestId));
+ public void requestCreateSessionByManager(
+ long managerRequestId, RoutingSessionInfo oldSession, MediaRoute2Info route) {
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRouter2::onRequestCreateControllerByManagerOnHandler,
+ MediaRouter2.this,
+ oldSession,
+ route,
+ managerRequestId));
}
}
@@ -1952,57 +2017,21 @@ public final class MediaRouter2 {
@Override
public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {
updateAllRoutesFromManager();
-
- List<MediaRoute2Info> filteredRoutes;
- synchronized (mLock) {
- filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
- }
- if (filteredRoutes.isEmpty()) {
- return;
- }
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- record.mExecutor.execute(
- () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
- }
}
@Override
public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {
updateAllRoutesFromManager();
-
- List<MediaRoute2Info> filteredRoutes;
- synchronized (mLock) {
- filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
- }
- if (filteredRoutes.isEmpty()) {
- return;
- }
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- record.mExecutor.execute(
- () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
- }
}
@Override
public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {
updateAllRoutesFromManager();
-
- List<MediaRoute2Info> filteredRoutes;
- synchronized (mLock) {
- filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
- }
- if (filteredRoutes.isEmpty()) {
- return;
- }
- for (RouteCallbackRecord record: mRouteCallbackRecords) {
- record.mExecutor.execute(
- () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
- }
}
@Override
- public void onTransferred(@NonNull RoutingSessionInfo oldSession,
- @NonNull RoutingSessionInfo newSession) {
+ public void onTransferred(
+ @NonNull RoutingSessionInfo oldSession, @NonNull RoutingSessionInfo newSession) {
if (!oldSession.isSystemSession()
&& !TextUtils.equals(mClientPackageName, oldSession.getClientPackageName())) {
return;
@@ -2018,7 +2047,6 @@ public final class MediaRouter2 {
return;
}
-
RoutingController oldController;
if (oldSession.isSystemSession()) {
mSystemController.setRoutingSessionInfo(
@@ -2041,8 +2069,8 @@ public final class MediaRouter2 {
}
@Override
- public void onTransferFailed(@NonNull RoutingSessionInfo session,
- @NonNull MediaRoute2Info route) {
+ public void onTransferFailed(
+ @NonNull RoutingSessionInfo session, @NonNull MediaRoute2Info route) {
if (!session.isSystemSession()
&& !TextUtils.equals(mClientPackageName, session.getClientPackageName())) {
return;
@@ -2083,8 +2111,8 @@ public final class MediaRouter2 {
}
@Override
- public void onDiscoveryPreferenceChanged(@NonNull String packageName,
- @NonNull RouteDiscoveryPreference preference) {
+ public void onDiscoveryPreferenceChanged(
+ @NonNull String packageName, @NonNull RouteDiscoveryPreference preference) {
if (!TextUtils.equals(mClientPackageName, packageName)) {
return;
}
diff --git a/media/java/android/media/NearbyDevice.java b/media/java/android/media/NearbyDevice.java
index c203e7b2b88b..dbcc6b716c8f 100644
--- a/media/java/android/media/NearbyDevice.java
+++ b/media/java/android/media/NearbyDevice.java
@@ -22,9 +22,10 @@ import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.List;
/**
* A parcelable representing a nearby device that can be used for media transfer.
@@ -35,6 +36,7 @@ import java.lang.annotation.RetentionPolicy;
* <li>a range zone specifying how far away this device is from the device with the media route.
* </li>
* </ul>
+ *
* @hide
*/
@SystemApi
@@ -69,7 +71,7 @@ public final class NearbyDevice implements Parcelable {
*
* @hide
*/
- @IntDef(prefix = { "RANGE_" }, value = {
+ @IntDef(prefix = {"RANGE_"}, value = {
RANGE_UNKNOWN,
RANGE_FAR,
RANGE_LONG,
@@ -77,7 +79,8 @@ public final class NearbyDevice implements Parcelable {
RANGE_WITHIN_REACH
})
@Retention(RetentionPolicy.SOURCE)
- public @interface RangeZone {}
+ public @interface RangeZone {
+ }
/**
* Gets a human-readable string of the range zone.
@@ -102,8 +105,17 @@ public final class NearbyDevice implements Parcelable {
}
}
- @NonNull private final String mMediaRoute2Id;
- @RangeZone private final int mRangeZone;
+ /**
+ * A list stores all the range and list from far to close, used for range comparison.
+ */
+ private static final List<Integer> RANGE_WEIGHT_LIST =
+ Arrays.asList(RANGE_UNKNOWN,
+ RANGE_FAR, RANGE_LONG, RANGE_CLOSE, RANGE_WITHIN_REACH);
+
+ @NonNull
+ private final String mMediaRoute2Id;
+ @RangeZone
+ private final int mRangeZone;
/** Creates a device object with the given ID and range zone. */
public NearbyDevice(@NonNull String mediaRoute2Id, @RangeZone int rangeZone) {
@@ -129,6 +141,22 @@ public final class NearbyDevice implements Parcelable {
}
};
+ /**
+ * Compares two ranges and return result.
+ *
+ * @return 0 means two ranges are the same, -1 means first range is closer, 1 means farther
+ *
+ * @hide
+ */
+ public static int compareRangeZones(@RangeZone int rangeZone, @RangeZone int anotherRangeZone) {
+ if (rangeZone == anotherRangeZone) {
+ return 0;
+ } else {
+ return RANGE_WEIGHT_LIST.indexOf(rangeZone) > RANGE_WEIGHT_LIST.indexOf(
+ anotherRangeZone) ? -1 : 1;
+ }
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 57730aca125f..52b00b7b43e5 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -986,7 +986,7 @@ public abstract class TvInteractiveAppService extends Service {
if (DEBUG) {
Log.d(TAG, "notifyContentAllowed");
}
- notifyContentAllowed();
+ onContentAllowed();
}
void notifyContentBlocked(TvContentRating rating) {
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index 959e756b8a16..bd960e704ca5 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -262,6 +262,7 @@ Result FilterClient::getFilterMq() {
if (mTunerFilter != nullptr) {
Status s = mTunerFilter->getQueueDesc(&aidlMqDesc);
+ res = ClientHelper::getServiceSpecificErrorCode(s);
if (s.isOk()) {
mFilterMQ = new (nothrow) AidlMQ(aidlMqDesc, false/*resetPointer*/);
EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index 22725254fef6..9e0a6eb476d3 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -140,8 +140,7 @@ public:
}
}
- void mountObb(const char* rawPath, const char* key, AStorageManager_obbCallbackFunc func,
- void* data) {
+ void mountObb(const char* rawPath, AStorageManager_obbCallbackFunc func, void* data) {
// Resolve path before sending to MountService
char canonicalPath[PATH_MAX];
if (realpath(rawPath, canonicalPath) == NULL) {
@@ -158,9 +157,7 @@ public:
ObbCallback* cb = registerObbCallback(func, data);
String16 rawPath16(rawPath);
String16 canonicalPath16(canonicalPath);
- String16 key16(key);
- mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
- cb->nonce, obbInfo);
+ mMountService->mountObb(rawPath16, canonicalPath16, mObbActionListener, cb->nonce, obbInfo);
}
void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
@@ -207,7 +204,11 @@ void AStorageManager_delete(AStorageManager* mgr) {
void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
AStorageManager_obbCallbackFunc cb, void* data) {
- mgr->mountObb(filename, key, cb, data);
+ if (key != nullptr && key[0] != '\0') {
+ ALOGE("mounting encrypted OBBs is no longer supported");
+ return;
+ }
+ mgr->mountObb(filename, cb, data);
}
void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
new file mode 100644
index 000000000000..f839b80d2e0c
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
@@ -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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <group android:scaleX="5.142857"
+ android:scaleY="5.142857"
+ android:translateY="2.5714285">
+ <path
+ android:pathData="M13.1235,1.01L5.1235,1C4.0235,1 3.1235,1.9 3.1235,3V17C3.1235,18.1 4.0235,19 5.1235,19H13.1235C14.2235,19 15.1235,18.1 15.1235,17V12.9765H13.1235V14H5.1235V6H13.1235V6.0034H15.1235V3C15.1235,1.9 14.2235,1.01 13.1235,1.01ZM13.1235,17H5.1235V16H13.1235V17ZM5.1235,4V3H13.1235V4H5.1235Z"
+ android:fillColor="#202124"
+ android:fillType="evenOdd"/>
+ <path
+ android:pathData="M10.6984,6.4016V13.3136L12.3596,12.3628H17.8731V6.4016H10.6984ZM16.3731,7.9016H12.1984V10.8628H16.3731V7.9016Z"
+ android:fillColor="#202124"
+ android:fillType="evenOdd"/>
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
new file mode 100644
index 000000000000..4ac4d04b184e
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_notifications.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/white"
+ android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
new file mode 100644
index 000000000000..d8b7f59185c8
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_storage.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/white"
+ android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
+</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 f30dadffa788..82fe72bee4e4 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -51,6 +51,11 @@
android:scrollbars="vertical"
android:layout_height="200dp" />
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/permission_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
</RelativeLayout>
<LinearLayout
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
new file mode 100644
index 000000000000..b8a0f7938f0b
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -0,0 +1,55 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/list_item_permission"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="5dp">
+
+ <ImageView
+ android:id="@+id/permission_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginTop="7dp"
+ android:layout_marginEnd="12dp"
+ android:contentDescription="Permission Icon"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:padding="6dp">
+
+ <TextView
+ android:id="@+id/permission_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
+
+ <TextView
+ android:id="@+id/permission_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="14sp"
+ android:textColor="?android:attr/textColorSecondary"/>
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 9626751679e1..c4ad432b092e 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -38,6 +38,12 @@
<!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
+ <!-- Apps permission will be granted of APP_STREAMING profile [CHAR LIMIT=30] -->
+ <string name="permission_apps">Apps</string>
+
+ <!-- Description of apps permission of APP_STREAMING profile [CHAR LIMIT=NONE] -->
+ <string name="permission_apps_summary">Stream your phone\u2019s apps</string>
+
<!-- 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 for your phone</string>
@@ -72,6 +78,18 @@
<!-- 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 contracts, 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>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 0fba250b200a..1b626911fdde 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -24,6 +24,9 @@ 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.Utils.getApplicationLabel;
import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
import static com.android.companiondevicemanager.Utils.getVendorHeaderIcon;
@@ -61,6 +64,7 @@ import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -122,8 +126,12 @@ public class CompanionDeviceActivity extends FragmentActivity implements
// The recycler view is only shown for multiple-device regular association request, after
// at least one matching device is found.
- private @Nullable RecyclerView mRecyclerView;
- private @Nullable DeviceListAdapter mAdapter;
+ private @Nullable RecyclerView mDeviceListRecyclerView;
+ private @Nullable DeviceListAdapter mDeviceAdapter;
+
+ // The recycler view is only shown for selfManaged association request.
+ private @Nullable RecyclerView mPermissionListRecyclerView;
+ private @Nullable PermissionListAdapter mPermissionListAdapter;
// The flag used to prevent double taps, that may lead to sending several requests for creating
// an association to CDM.
@@ -133,6 +141,8 @@ public class CompanionDeviceActivity extends FragmentActivity implements
// onActivityResult() after the association is created.
private @Nullable DeviceFilterPair<?> mSelectedDevice;
+ private @Nullable List<Integer> mPermissionTypes;
+
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate()");
@@ -242,8 +252,11 @@ public class CompanionDeviceActivity extends FragmentActivity implements
mVendorHeaderName = findViewById(R.id.vendor_header_name);
mVendorHeaderButton = findViewById(R.id.vendor_header_button);
- mRecyclerView = findViewById(R.id.device_list);
- mAdapter = new DeviceListAdapter(this, this::onListItemClick);
+ mDeviceListRecyclerView = findViewById(R.id.device_list);
+ mDeviceAdapter = new DeviceListAdapter(this, this::onListItemClick);
+
+ mPermissionListRecyclerView = findViewById(R.id.permission_list);
+ mPermissionListAdapter = new PermissionListAdapter(this);
mButtonAllow = findViewById(R.id.btn_positive);
mButtonNotAllow = findViewById(R.id.btn_negative);
@@ -359,7 +372,8 @@ public class CompanionDeviceActivity extends FragmentActivity implements
final Drawable vendorIcon;
final CharSequence vendorName;
final Spanned title;
- final Spanned summary;
+
+ mPermissionTypes = new ArrayList<>();
try {
vendorIcon = getVendorHeaderIcon(this, packageName, userId);
@@ -372,33 +386,36 @@ public class CompanionDeviceActivity extends FragmentActivity implements
switch (deviceProfile) {
case DEVICE_PROFILE_APP_STREAMING:
- title = getHtmlFromResources(this, R.string.title_app_streaming, appLabel);
- summary = getHtmlFromResources(
- this, R.string.summary_app_streaming, appLabel, deviceName);
+ title = getHtmlFromResources(this, R.string.title_app_streaming, deviceName);
+ mPermissionTypes.add(TYPE_APPS);
break;
case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION:
- title = getHtmlFromResources(this, R.string.title_automotive_projection, appLabel);
- summary = getHtmlFromResources(
- this, R.string.summary_automotive_projection, appLabel, deviceName);
+ title = getHtmlFromResources(
+ this, R.string.title_automotive_projection, deviceName);
break;
case DEVICE_PROFILE_COMPUTER:
- title = getHtmlFromResources(this, R.string.title_computer, appLabel);
- summary = getHtmlFromResources(
- this, R.string.summary_computer, appLabel, deviceName);
+ title = getHtmlFromResources(this, R.string.title_computer, deviceName);
+ mPermissionTypes.add(TYPE_NOTIFICATION);
+ mPermissionTypes.add(TYPE_STORAGE);
break;
default:
throw new RuntimeException("Unsupported profile " + deviceProfile);
}
+ mSummary.setVisibility(View.GONE);
+
+ mPermissionListAdapter.setPermissionType(mPermissionTypes);
+ mPermissionListRecyclerView.setAdapter(mPermissionListAdapter);
+ mPermissionListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+
mTitle.setText(title);
- mSummary.setText(summary);
mVendorHeaderImage.setImageDrawable(vendorIcon);
mVendorHeaderName.setText(vendorName);
- mRecyclerView.setVisibility(View.GONE);
+ mDeviceListRecyclerView.setVisibility(View.GONE);
mVendorHeader.setVisibility(View.VISIBLE);
}
@@ -411,7 +428,8 @@ public class CompanionDeviceActivity extends FragmentActivity implements
deviceFilterPairs -> updateSingleDeviceUi(
deviceFilterPairs, deviceProfile, appLabel));
- mRecyclerView.setVisibility(View.GONE);
+ mPermissionListRecyclerView.setVisibility(View.GONE);
+ mDeviceListRecyclerView.setVisibility(View.GONE);
}
private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
@@ -460,15 +478,15 @@ public class CompanionDeviceActivity extends FragmentActivity implements
mTitle.setText(title);
mSummary.setText(summary);
- mAdapter = new DeviceListAdapter(this, this::onListItemClick);
+ mDeviceAdapter = new DeviceListAdapter(this, this::onListItemClick);
// TODO: hide the list and show a spinner until a first device matching device is found.
- mRecyclerView.setAdapter(mAdapter);
- mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+ mDeviceListRecyclerView.setAdapter(mDeviceAdapter);
+ mDeviceListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
CompanionDeviceDiscoveryService.getScanResult().observe(
/* lifecycleOwner */ this,
- /* observer */ mAdapter);
+ /* observer */ mDeviceAdapter);
// "Remove" consent button: users would need to click on the list item.
mButtonAllow.setVisibility(View.GONE);
@@ -477,14 +495,14 @@ public class CompanionDeviceActivity extends FragmentActivity implements
private void onListItemClick(int position) {
if (DEBUG) Log.d(TAG, "onListItemClick() " + position);
- final DeviceFilterPair<?> selectedDevice = mAdapter.getItem(position);
+ final DeviceFilterPair<?> selectedDevice = mDeviceAdapter.getItem(position);
if (mSelectedDevice != null) {
if (DEBUG) Log.w(TAG, "Already selected.");
return;
}
// Notify the adapter to highlight the selected item.
- mAdapter.setSelectedPosition(position);
+ mDeviceAdapter.setSelectedPosition(position);
mSelectedDevice = requireNonNull(selectedDevice);
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index e5513b074865..8babd3ade1eb 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -15,9 +15,10 @@
*/
package com.android.companiondevicemanager;
+
+import static com.android.companiondevicemanager.Utils.getIcon;
+
import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -60,11 +61,11 @@ class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.ViewHolde
R.layout.list_item_device, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
if (viewType == TYPE_WIFI) {
- viewHolder.mImageView.setImageDrawable(getIcon(
- com.android.internal.R.drawable.ic_wifi_signal_3));
+ viewHolder.mImageView.setImageDrawable(
+ getIcon(mContext, com.android.internal.R.drawable.ic_wifi_signal_3));
} else {
- viewHolder.mImageView.setImageDrawable(getIcon(
- android.R.drawable.stat_sys_data_bluetooth));
+ viewHolder.mImageView.setImageDrawable(
+ getIcon(mContext, android.R.drawable.stat_sys_data_bluetooth));
}
return viewHolder;
}
@@ -115,12 +116,6 @@ class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.ViewHolde
return mDevices.get(position).getDevice() instanceof android.net.wifi.ScanResult;
}
- private Drawable getIcon(int resId) {
- Drawable icon = mContext.getResources().getDrawable(resId, null);
- icon.setTint(Color.DKGRAY);
- return icon;
- }
-
public interface OnItemClickListener {
void onItemClick(int position);
}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
new file mode 100644
index 000000000000..895b729ea8c7
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.companiondevicemanager;
+
+import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
+import static com.android.companiondevicemanager.Utils.getIcon;
+
+import static java.util.Collections.unmodifiableMap;
+
+import android.content.Context;
+import android.text.Spanned;
+import android.util.ArrayMap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.List;
+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;
+
+ 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);
+ 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);
+ 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);
+ sIconMap = unmodifiableMap(map);
+ }
+
+ PermissionListAdapter(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.list_item_permission, parent, false);
+ ViewHolder viewHolder = new ViewHolder(view);
+ viewHolder.mPermissionIcon.setImageDrawable(getIcon(mContext, sIconMap.get(viewType)));
+
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ int type = getItemViewType(position);
+ final Spanned title = getHtmlFromResources(mContext, sTitleMap.get(type));
+ final Spanned summary = getHtmlFromResources(mContext, sSummaryMap.get(type));
+
+ holder.mPermissionName.setText(title);
+ holder.mPermissionSummary.setText(summary);
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return mPermissions.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPermissions != null ? mPermissions.size() : 0;
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ private final TextView mPermissionName;
+ private final TextView mPermissionSummary;
+ private final ImageView mPermissionIcon;
+ 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);
+ }
+ }
+
+ void setPermissionType(List<Integer> permissions) {
+ mPermissions = permissions;
+ }
+}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
index 76bbcfb79155..d5b2f0a748f1 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -121,6 +122,12 @@ class Utils {
return appInfo;
}
+ static @NonNull Drawable getIcon(@NonNull Context context, int resId) {
+ Drawable icon = context.getResources().getDrawable(resId, null);
+ icon.setTint(Color.DKGRAY);
+ return icon;
+ }
+
static void runOnMainThread(Runnable runnable) {
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
runnable.run();
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
index a48f94b66def..da5f88dc3b7e 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -189,14 +189,14 @@ public class NetworkIdentity {
public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
- proto.write(NetworkIdentityProto.TYPE_FIELD_NUMBER, mType);
+ proto.write(NetworkIdentityProto.TYPE, mType);
// TODO: dump mRatType as well.
- proto.write(NetworkIdentityProto.ROAMING_FIELD_NUMBER, mRoaming);
- proto.write(NetworkIdentityProto.METERED_FIELD_NUMBER, mMetered);
- proto.write(NetworkIdentityProto.DEFAULT_NETWORK_FIELD_NUMBER, mDefaultNetwork);
- proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK_FIELD_NUMBER, mOemManaged);
+ proto.write(NetworkIdentityProto.ROAMING, mRoaming);
+ proto.write(NetworkIdentityProto.METERED, mMetered);
+ proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
+ proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
proto.end(start);
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
index 56461babfe49..ad3a958a680e 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
@@ -222,7 +222,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
final long start = proto.start(tag);
for (NetworkIdentity ident : this) {
- ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES_FIELD_NUMBER);
+ ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
}
proto.end(start);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 67d48f0000d5..735c44d5c87e 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
@@ -732,19 +732,19 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W
final long start = proto.start(tag);
for (Key key : getSortedKeys()) {
- final long startStats = proto.start(NetworkStatsCollectionProto.STATS_FIELD_NUMBER);
+ final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
// Key
- final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY_FIELD_NUMBER);
- key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY_FIELD_NUMBER);
- proto.write(NetworkStatsCollectionKeyProto.UID_FIELD_NUMBER, key.uid);
- proto.write(NetworkStatsCollectionKeyProto.SET_FIELD_NUMBER, key.set);
- proto.write(NetworkStatsCollectionKeyProto.TAG_FIELD_NUMBER, key.tag);
+ final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
+ key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
+ proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
+ proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
+ proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
proto.end(startKey);
// Value
final NetworkStatsHistory history = mStats.get(key);
- history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY_FIELD_NUMBER);
+ history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
proto.end(startStats);
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
index 822a16e0bb41..301fef944169 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
@@ -915,18 +915,18 @@ public final class NetworkStatsHistory implements Parcelable {
public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
- proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS_FIELD_NUMBER, bucketDuration);
+ proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
for (int i = 0; i < bucketCount; i++) {
- final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS_FIELD_NUMBER);
+ final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
- proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS_FIELD_NUMBER,
+ proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS,
bucketStart[i]);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES_FIELD_NUMBER, rxBytes, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS_FIELD_NUMBER, rxPackets, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES_FIELD_NUMBER, txBytes, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS_FIELD_NUMBER, txPackets, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS_FIELD_NUMBER, operations, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
proto.end(startBucket);
}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
index 151c90dd4155..3b93f1a1905f 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
@@ -25,9 +25,9 @@ import static android.net.NetworkStats.UID_ALL;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.net.ConnectivityManager;
import android.net.NetworkStats;
import android.net.UnderlyingNetworkInfo;
+import android.os.ServiceSpecificException;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -35,6 +35,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ProcFileReader;
import com.android.net.module.util.CollectionUtils;
+import com.android.server.BpfNetMaps;
import libcore.io.IoUtils;
@@ -74,6 +75,8 @@ public class NetworkStatsFactory {
private final Context mContext;
+ private final BpfNetMaps mBpfNetMaps;
+
/**
* Guards persistent data access in this class
*
@@ -170,6 +173,7 @@ public class NetworkStatsFactory {
mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
mUseBpfStats = useBpfStats;
+ mBpfNetMaps = new BpfNetMaps();
synchronized (mPersistentDataLock) {
mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
@@ -297,12 +301,14 @@ public class NetworkStatsFactory {
}
@GuardedBy("mPersistentDataLock")
- private void requestSwapActiveStatsMapLocked() {
- // Do a active map stats swap. When the binder call successfully returns,
- // the system server should be able to safely read and clean the inactive map
- // without race problem.
- final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
- cm.swapActiveStatsMap();
+ private void requestSwapActiveStatsMapLocked() throws IOException {
+ try {
+ // Do a active map stats swap. Once the swap completes, this code
+ // can read and clean the inactive map without races.
+ mBpfNetMaps.swapActiveStatsMap();
+ } catch (ServiceSpecificException e) {
+ throw new IOException(e);
+ }
}
/**
@@ -328,11 +334,7 @@ public class NetworkStatsFactory {
final NetworkStats stats =
new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */);
if (mUseBpfStats) {
- try {
- requestSwapActiveStatsMapLocked();
- } catch (RuntimeException e) {
- throw new IOException(e);
- }
+ requestSwapActiveStatsMapLocked();
// Stats are always read from the inactive map, so they must be read after the
// swap
if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
index a006cd597568..f62765d07427 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
@@ -471,11 +471,11 @@ public class NetworkStatsRecorder {
public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
if (mPending != null) {
- proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES_FIELD_NUMBER,
+ proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES,
mPending.getTotalBytes());
}
getOrLoadCompleteLocked().dumpDebug(proto,
- NetworkStatsRecorderProto.COMPLETE_HISTORY_FIELD_NUMBER);
+ NetworkStatsRecorderProto.COMPLETE_HISTORY);
proto.end(start);
}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index ef6f39a5c040..b5e05395f2e8 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -2132,15 +2132,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// TODO Right now it writes all history. Should it limit to the "since-boot" log?
- dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES_FIELD_NUMBER,
+ dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES,
mActiveIfaces);
- dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES_FIELD_NUMBER,
+ dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES,
mActiveUidIfaces);
- mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS_FIELD_NUMBER);
- mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS_FIELD_NUMBER);
- mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS_FIELD_NUMBER);
+ mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
+ mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
+ mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
mUidTagRecorder.dumpDebugLocked(proto,
- NetworkStatsServiceDumpProto.UID_TAG_STATS_FIELD_NUMBER);
+ NetworkStatsServiceDumpProto.UID_TAG_STATS);
proto.flush();
}
@@ -2150,8 +2150,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
for (int i = 0; i < ifaces.size(); i++) {
final long start = proto.start(tag);
- proto.write(NetworkInterfaceProto.INTERFACE_FIELD_NUMBER, ifaces.keyAt(i));
- ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES_FIELD_NUMBER);
+ proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
+ ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
proto.end(start);
}
diff --git a/packages/SystemUI/res/drawable/ic_account_circle.xml b/packages/SettingsLib/res/drawable/ic_account_circle.xml
index 5ca99f32771b..5ca99f32771b 100644
--- a/packages/SystemUI/res/drawable/ic_account_circle.xml
+++ b/packages/SettingsLib/res/drawable/ic_account_circle.xml
diff --git a/packages/SystemUI/res/drawable/ic_account_circle_filled.xml b/packages/SettingsLib/res/drawable/ic_account_circle_filled.xml
index 47c553b52123..47c553b52123 100644
--- a/packages/SystemUI/res/drawable/ic_account_circle_filled.xml
+++ b/packages/SettingsLib/res/drawable/ic_account_circle_filled.xml
diff --git a/packages/SystemUI/res/drawable/ic_add_supervised_user.xml b/packages/SettingsLib/res/drawable/ic_add_supervised_user.xml
index 627743ed1669..627743ed1669 100644
--- a/packages/SystemUI/res/drawable/ic_add_supervised_user.xml
+++ b/packages/SettingsLib/res/drawable/ic_add_supervised_user.xml
diff --git a/packages/SystemUI/res/drawable/kg_bg_avatar.xml b/packages/SettingsLib/res/drawable/user_avatar_bg.xml
index addb3f7508f5..1f50496f3a5c 100644
--- a/packages/SystemUI/res/drawable/kg_bg_avatar.xml
+++ b/packages/SettingsLib/res/drawable/user_avatar_bg.xml
@@ -22,7 +22,7 @@
android:viewportHeight="100">
<path
- android:fillColor="@color/kg_user_switcher_avatar_background"
+ android:fillColor="@color/user_avatar_color_bg"
android:pathData="M50,50m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0"/>
</vector>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index 5e8779fa289a..7ab2ed9481b7 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -36,7 +36,8 @@
<color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
<color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
-
<color name="dark_mode_icon_color_single_tone">#99000000</color>
<color name="light_mode_icon_color_single_tone">#ffffff</color>
+
+ <color name="user_avatar_color_bg">?android:attr/colorBackgroundFloating</color>
</resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index da0381b68278..e524405a39d5 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1426,8 +1426,12 @@
<string name="user_switch_to_user">Switch to <xliff:g id="user_name" example="John Doe">%s</xliff:g></string>
<!-- Dialog message when creating a new user [CHAR LIMIT=NONE] -->
<string name="creating_new_user_dialog_message">Creating new user…</string>
+ <!-- Dialog message when creating a new guest [CHAR LIMIT=NONE] -->
+ <string name="creating_new_guest_dialog_message">Creating new guest…</string>
<!-- Text shown to notify that the creation of new user has failed. [CHAR LIMIT=40] -->
<string name="add_user_failed">Failed to create a new user</string>
+ <!-- Text shown to notify that the creation of new guest has failed. [CHAR LIMIT=40] -->
+ <string name="add_guest_failed">Failed to create a new guest</string>
<!-- Title for the preference to enter the nickname of the user to display in the user switcher [CHAR LIMIT=25]-->
<string name="user_nickname">Nickname</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 5e2f31010900..7573177565a4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -24,9 +24,9 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothHidDevice;
import android.bluetooth.BluetoothHidHost;
+import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothMapClient;
import android.bluetooth.BluetoothPan;
@@ -159,10 +159,8 @@ public class LocalBluetoothProfileManager {
if (mHfpClientProfile == null && supportedList.contains(BluetoothProfile.HEADSET_CLIENT)) {
if (DEBUG) Log.d(TAG, "Adding local HfpClient profile");
mHfpClientProfile = new HfpClientProfile(mContext, mDeviceManager, this);
- addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME,
- BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED,
- BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED,
- BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
+ addProfile(mHfpClientProfile, HfpClientProfile.NAME,
+ BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
}
if (mMapClientProfile == null && supportedList.contains(BluetoothProfile.MAP_CLIENT)) {
if (DEBUG) Log.d(TAG, "Adding local MAP CLIENT profile");
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index c7599623c465..3984ee9aa007 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -35,6 +35,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
+import android.media.NearbyDevice;
import android.text.TextUtils;
import android.util.Log;
@@ -77,6 +78,8 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
private int mConnectedRecord;
private int mState;
+ @NearbyDevice.RangeZone
+ private int mRangeZone = NearbyDevice.RANGE_UNKNOWN;
protected final Context mContext;
protected final MediaRoute2Info mRouteInfo;
@@ -136,6 +139,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
getId());
}
+ public @NearbyDevice.RangeZone int getRangeZone() {
+ return mRangeZone;
+ }
+
+ public void setRangeZone(@NearbyDevice.RangeZone int rangeZone) {
+ mRangeZone = rangeZone;
+ }
+
/**
* Get name from MediaDevice.
*
@@ -319,6 +330,11 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
}
}
+ // Both devices have same connection status, compare the range zone
+ if (NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone()) != 0) {
+ return NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone());
+ }
+
if (mType == another.mType) {
// Check device is muting expected device
if (isMutingExpectedDevice()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java b/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
index 075635c87b1b..dd86bec9126c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
@@ -31,11 +31,15 @@ import com.android.settingslib.R;
public class UserCreatingDialog extends AlertDialog {
public UserCreatingDialog(Context context) {
+ this(context, false);
+ }
+
+ public UserCreatingDialog(Context context, boolean isGuest) {
// hardcoding theme to be consistent with UserSwitchingDialog's theme
// todo replace both to adapt to the device's theme
super(context, com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog_Alert);
- inflateContent();
+ inflateContent(isGuest);
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
@@ -44,12 +48,14 @@ public class UserCreatingDialog extends AlertDialog {
getWindow().setAttributes(attrs);
}
- private void inflateContent() {
+ private void inflateContent(boolean isGuest) {
// using the same design as UserSwitchingDialog
setCancelable(false);
View view = LayoutInflater.from(getContext())
.inflate(R.layout.user_creation_progress_dialog, null);
- String message = getContext().getString(R.string.creating_new_user_dialog_message);
+ String message = getContext().getString(isGuest
+ ? R.string.creating_new_guest_dialog_message
+ : R.string.creating_new_user_dialog_message);
view.setAccessibilityPaneTitle(message);
((TextView) view.findViewById(R.id.message)).setText(message);
setView(view);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
index 9ebdba300266..1d08711715c3 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
@@ -150,23 +150,6 @@ public class AvatarPhotoControllerTest {
}
@Test
- public void takePhotoIsNotFollowedByCropIntentWhenCropNotSupported() throws IOException {
- when(mMockAvatarUi.startSystemActivityForResult(any(), anyInt())).thenReturn(false);
-
- File file = new File(mImagesDir, "file.txt");
- saveBitmapToFile(file);
-
- Intent intent = new Intent();
- intent.setData(Uri.parse(
- "content://com.android.settingslib.test/my_cache/multi_user/file.txt"));
- mController.onActivityResult(
- REQUEST_CODE_TAKE_PHOTO, Activity.RESULT_OK, intent);
-
- verify(mMockAvatarUi, never()).startActivityForResult(any(), anyInt());
- verify(mMockAvatarUi, never()).startSystemActivityForResult(any(), anyInt());
- }
-
- @Test
public void choosePhotoIsFollowedByCrop() throws IOException {
new File(mImagesDir, "file.txt").createNewFile();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index c122a37d0f79..179a498b7397 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -31,6 +31,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
+import android.media.NearbyDevice;
import android.os.Parcel;
import com.android.settingslib.bluetooth.A2dpProfile;
@@ -200,6 +201,18 @@ public class MediaDeviceTest {
}
@Test
+ public void compareTo_differentRange_sortWithRange() {
+ mBluetoothMediaDevice1.setRangeZone(NearbyDevice.RANGE_FAR);
+ mBluetoothMediaDevice2.setRangeZone(NearbyDevice.RANGE_CLOSE);
+ mMediaDevices.add(mBluetoothMediaDevice1);
+ mMediaDevices.add(mBluetoothMediaDevice2);
+
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+ Collections.sort(mMediaDevices, COMPARATOR);
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2);
+ }
+
+ @Test
public void compareTo_carKit_info_carKitFirst() {
when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
mMediaDevices.add(mInfoMediaDevice1);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 1c5bf81faf3e..3c29a803ffbb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2252,12 +2252,14 @@ class SettingsProtoDumpUtil {
Settings.Secure.MULTI_PRESS_TIMEOUT,
SecureSettingsProto.MULTI_PRESS_TIMEOUT);
+ final long navBar = p.start(SecureSettingsProto.NAV_BAR);
dumpSetting(s, p,
Settings.Secure.NAV_BAR_FORCE_VISIBLE,
SecureSettingsProto.NavBar.NAV_BAR_FORCE_VISIBLE);
dumpSetting(s, p,
Settings.Secure.NAV_BAR_KIDS_MODE,
SecureSettingsProto.NavBar.NAV_BAR_KIDS_MODE);
+ p.end(navBar);
dumpSetting(s, p,
Settings.Secure.NAVIGATION_MODE,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 3f4372bd78ff..057a9b05de58 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -271,6 +271,7 @@ public class SettingsBackupTest {
Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
Settings.Global.SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS,
+ Settings.Global.STYLUS_HANDWRITING_ENABLED,
Settings.Global.ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT,
Settings.Global.ENABLE_MULTI_SLOT_TIMEOUT_MILLIS,
Settings.Global.ENHANCED_4G_MODE_ENABLED,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c0e2b2ef361f..dae63a8b0e3c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -210,6 +210,7 @@
<uses-permission android:name="android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
<uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
+ <uses-permission android:name="android.permission.PROVISION_DEMO_DEVICE" />
<uses-permission android:name="android.permission.QUERY_ADMIN_POLICY" />
<uses-permission android:name="android.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES" />
<uses-permission android:name="android.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS" />
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 183584227087..3f7e0f0fb527 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -33,6 +33,7 @@ import android.view.ViewGroup
import android.view.ViewGroupOverlay
import android.widget.FrameLayout
import com.android.internal.jank.InteractionJankMonitor
+import java.util.LinkedList
import kotlin.math.min
private const val TAG = "GhostedViewLaunchAnimatorController"
@@ -81,21 +82,51 @@ open class GhostedViewLaunchAnimatorController(
* [backgroundView].
*/
private var backgroundDrawable: WrappedDrawable? = null
- private val backgroundInsets by lazy { getBackground()?.opticalInsets ?: Insets.NONE }
+ private val backgroundInsets by lazy { background?.opticalInsets ?: Insets.NONE }
private var startBackgroundAlpha: Int = 0xFF
private val ghostedViewLocation = IntArray(2)
private val ghostedViewState = LaunchAnimator.State()
/**
- * Return the background of the [ghostedView]. This background will be used to draw the
- * background of the background view that is expanding up to the final animation position. This
- * is called at the start of the animation.
+ * The background of the [ghostedView]. This background will be used to draw the background of
+ * the background view that is expanding up to the final animation position.
*
* Note that during the animation, the alpha value value of this background will be set to 0,
* then set back to its initial value at the end of the animation.
*/
- protected open fun getBackground(): Drawable? = ghostedView.background
+ private val background: Drawable?
+
+ init {
+ /** Find the first view with a background in [view] and its children. */
+ fun findBackground(view: View): Drawable? {
+ if (view.background != null) {
+ return view.background
+ }
+
+ // Perform a BFS to find the largest View with background.
+ val views = LinkedList<View>().apply {
+ add(view)
+ }
+
+ while (views.isNotEmpty()) {
+ val v = views.removeFirst()
+ if (v.background != null) {
+ return v.background
+ }
+
+ if (v is ViewGroup) {
+ for (i in 0 until v.childCount) {
+ views.add(v.getChildAt(i))
+ }
+ }
+ }
+
+ return null
+ }
+
+ background = findBackground(ghostedView)
+ }
/**
* Set the corner radius of [background]. The background is the one that was returned by
@@ -113,7 +144,7 @@ open class GhostedViewLaunchAnimatorController(
/** Return the current top corner radius of the background. */
protected open fun getCurrentTopCornerRadius(): Float {
- val drawable = getBackground() ?: return 0f
+ val drawable = background ?: return 0f
val gradient = findGradientDrawable(drawable) ?: return 0f
// TODO(b/184121838): Support more than symmetric top & bottom radius.
@@ -122,7 +153,7 @@ open class GhostedViewLaunchAnimatorController(
/** Return the current bottom corner radius of the background. */
protected open fun getCurrentBottomCornerRadius(): Float {
- val drawable = getBackground() ?: return 0f
+ val drawable = background ?: return 0f
val gradient = findGradientDrawable(drawable) ?: return 0f
// TODO(b/184121838): Support more than symmetric top & bottom radius.
@@ -162,9 +193,8 @@ open class GhostedViewLaunchAnimatorController(
// We wrap the ghosted view background and use it to draw the expandable background. Its
// alpha will be set to 0 as soon as we start drawing the expanding background.
- val drawable = getBackground()
- startBackgroundAlpha = drawable?.alpha ?: 0xFF
- backgroundDrawable = WrappedDrawable(drawable)
+ startBackgroundAlpha = background?.alpha ?: 0xFF
+ backgroundDrawable = WrappedDrawable(background)
backgroundView?.background = backgroundDrawable
// Create a ghost of the view that will be moving and fading out. This allows to fade out
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index c97ebe8d5559..e74b6c78ec80 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -41,6 +41,14 @@
-keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.Dagger** { !synthetic *; }
-keep,allowoptimization,allowaccessmodification class com.android.systemui.tv.Dagger** { !synthetic *; }
+# Prevent optimization or access modification of any referenced code that may
+# conflict with code in the bootclasspath.
+# TODO(b/222468116): Resolve such collisions in the build system.
+-keepnames class android.**.nano.** { *; }
+-keepnames class com.android.**.nano.** { *; }
+-keepnames class com.android.internal.protolog.** { *; }
+-keepnames class android.hardware.common.** { *; }
+
# Allows proguard to make private and protected methods and fields public as
# part of optimization. This lets proguard inline trivial getter/setter methods.
-allowaccessmodification
diff --git a/packages/SystemUI/res/color/kg_user_avatar_frame.xml b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
index 174981e2a660..a143194f331d 100644
--- a/packages/SystemUI/res/color/kg_user_avatar_frame.xml
+++ b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
@@ -18,6 +18,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
- android:color="@color/kg_user_switcher_avatar_background" />
- <item android:color="@color/kg_user_switcher_avatar_background" />
+ android:color="@color/user_avatar_color_bg" />
+ <item android:color="@color/user_avatar_color_bg" />
</selector>
diff --git a/packages/SystemUI/res/drawable/user_switcher_icon_large.xml b/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
index b78b2216c9f9..1ed75537059a 100644
--- a/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
+++ b/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
@@ -36,7 +36,7 @@
</item>
<!-- Where the user drawable/bitmap will be placed -->
<item
- android:drawable="@drawable/kg_bg_avatar"
+ android:drawable="@drawable/user_avatar_bg"
android:width="@dimen/bouncer_user_switcher_icon_size"
android:height="@dimen/bouncer_user_switcher_icon_size"
android:top="@dimen/user_switcher_icon_large_margin"
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index 1cbc3c284874..d0f4903a3421 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -42,17 +42,6 @@
app:layout_constraintEnd_toEndOf="parent">
<com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/dream_overlay_assistant_guest_mode_enabled"
- android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
- android:layout_height="match_parent"
- android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
- android:src="@drawable/ic_account_circle"
- android:tint="@android:color/white"
- android:visibility="gone"
- android:contentDescription=
- "@string/dream_overlay_status_bar_assistant_guest_mode_enabled" />
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/dream_overlay_alarm_set"
android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 51211a0c0d2a..05343e75b448 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -129,7 +129,7 @@
style="@style/Widget.Dialog.Button.BorderButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/keyboard_key_media_stop"
+ android:text="@string/media_output_dialog_button_stop_casting"
android:visibility="gone"/>
<Space
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index e4706e263a0f..ef030baa967b 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -26,9 +26,6 @@
android:layout_height="match_parent"
android:background="@android:color/transparent">
- <include layout="@layout/communal_host_view"
- android:visibility="gone"/>
-
<ViewStub
android:id="@+id/keyguard_qs_user_switch_stub"
android:layout="@layout/keyguard_qs_user_switch"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
index e33f186dcbb7..c4d8d55f74e2 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
@@ -21,8 +21,6 @@
android:layout_height="@dimen/notification_section_header_height"
android:paddingStart="4dp"
android:paddingEnd="4dp"
- android:focusable="true"
- android:clickable="true"
>
<LinearLayout
@@ -46,6 +44,7 @@
android:id="@+id/header_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:focusable="true"
android:forceHasOverlappingRendering="false"
android:text="@string/notification_section_header_gentle"
/>
@@ -57,6 +56,7 @@
android:layout_height="48dp"
android:src="@drawable/status_bar_notification_section_header_clear_btn"
android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
+ android:focusable="true"
android:scaleType="center"
android:tintMode="src_in"
android:visibility="gone"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 42955caf5ae9..c0fdf689cfc2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Stelsel-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Battery kan binnekort afloop"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> oor"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Kan nie deur USB laai nie"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Gebruik die laaier wat jy saam met jou toestel gekry het"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesig is gestaaf"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestig"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestig om te voltooi"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gebruik PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gebruik patroon"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Maak toe"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"volkome stilte"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"net wekkers"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Moenie Steur Nie."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aan."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wekker gestel vir <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Nageregkas"</string>
<string name="start_dreams" msgid="9131802557946276718">"Sluimerskerm"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Moenie Steur Nie"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen saamgebinde toestelle beskikbaar nie"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Kennisgewings"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vee alle stil kennisgewings uit"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Laer gegradeer"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, onderbreek Moenie Steur Nie"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel, onderbreek Moenie Steur Nie"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiek"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Moenie Steur Nie"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppieskortpad"</string>
<string name="battery" msgid="769686279459897127">"Battery"</string>
<string name="headset" msgid="4485892374984466437">"Kopstuk"</string>
@@ -684,6 +697,10 @@
<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 af"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is af"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Moenie Steur Nie is af"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'n Outomatiese reël of program het Moenie Steur Nie aangeskakel."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Programme wat op die agtergrond loop"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tik vir besonderhede oor battery- en datagebruik"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Skakel mobiele data af?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(werk)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Oproep"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(deur <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ligging"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
<string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Sien onlangse boodskappe, gemiste oproepe en statusopdaterings"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbreek deur Moenie Steur nie"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> het \'n boodskap gestuur: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> het \'n prent gestuur"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> het \'n statusopdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiewe programme</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiewe program</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuwe inligting"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiewe programme"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestop"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Wysig gekopieerde teks"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Wysig gekopieerde prent"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Stuur na toestel in die omtrek"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"Voeg by"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Bestuur gebruikers"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Sleep na verdeelde skerm word nie vir hierdie kennisgewing gesteun nie."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑fi onbeskikbaar"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitmodus"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistent-gasmodus is geaktiveer"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 03ae0e41ff41..43ad0057d2ba 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"የስርዓት UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ባትሪ በቅርቡ ሊያልቅ ይችላል"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ይቀራል"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"በዩኤስቢ በኩል ኃይል መሙላት አይቻልም"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ከእርስዎ መሣሪያ ጋር የመጣውን ኃይል መሙያ ይጠቀሙ"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"መልክ ተረጋግጧል"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ተረጋግጧል"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ፒን ይጠቀሙ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ሥርዓተ ጥለትን ተጠቀም"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ዝጋ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ሙሉ ለሙሉ ጸጥታ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ማንቂያዎች ብቻ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"አትረብሽ።"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ብሉቱዝ።"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ብሉቱዝ በርቷል።"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ማንቂያ ለ<xliff:g id="TIME">%s</xliff:g> ተዋቅሯል።"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"የማወራረጃ ምግቦች መያዣ"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ምንም የተጣመሩ መሣሪያዎች አይገኝም"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ባትሪ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ማሳወቂያዎች"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ውይይቶች"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ሁኔታ:&lt;/b&gt; ዝቅተኛ ደረጃ ተሰጥቶታል"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ አትረብሽን ያቋርጣል"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ቅድሚያ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ኤስኤምኤስ"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ሙዚቃ"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"የቀን መቁጠሪያ"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"አትረብሽ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"የድምፅ አዝራሮች አቋራጭ"</string>
<string name="battery" msgid="769686279459897127">"ባትሪ"</string>
<string name="headset" msgid="4485892374984466437">"ጆሮ ማዳመጫ"</string>
@@ -684,6 +697,10 @@
<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 ጠፍቷል"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ብሉቱዝ ጠፍቷል"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"አትረብሽ ጠፍቷል"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"አትረብሽ በአንድ ራስ-ሰር ደንብ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"አትረብሽ በአንድ መተግበሪያ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"አትረብሽ በአንድ ራስ-ሰር ደንብ ወይም መተግበሪያ በርቷል።"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"የተንቀሳቃሽ ስልክ ውሂብ ይጥፋ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ስራ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"የስልክ ጥሪ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(በ<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> በኩል)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ካሜራ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"አካባቢ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ማይክሮፎን"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ተቋርጧል)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"መቀየር አይቻልም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
<string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"የቅርብ ጊዜ መልዕክቶችን፣ ያመለጡ ጥሪዎች እና፣ የሁኔታ ዝመናዎችን ይመልከቱ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ውይይት"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"በአትረብሽ ባለበት ቆሟል"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> መልዕክት ልከዋል፦ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ምስል ልኳል"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> የሁኔታ ዝማኔ አለው፦ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ገቢር መተግበሪያዎች</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ገቢር መተግበሪያዎች</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"አዲስ መረጃ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ገቢር መተግበሪያዎች"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"መቆሚያ"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ቆሟል"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"የተቀዳ ጽሁፍ አርትዕ ያድርጉ"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"የተቀዳ ምስል አርትዕ ያድርጉ"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"በአቅራቢያ ወዳለ መሳሪያ ይላኩ"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"አክል"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ተጠቃሚዎችን ያስተዳድሩ"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ይህ ማሳወቂያ ወደ Splitscreen መጎተትን አይደግፍም።"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"የረዳት እንግዳ ሁነታ ነቅቷል"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 38dcb89cd56d..5ec5e9b537f0 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"واجهة مستخدم النظام"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"قد ينفد شحن البطارية قريبًا"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"متبقي <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"‏يتعذّر الشحن باستخدام USB."</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"استخدم الشاحن المرفق بجهازك."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"تمّت مصادقة الوجه."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استخدام رقم تعريف شخصي"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استخدام نقش"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"إغلاق"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"كتم الصوت تمامًا"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"المنبِّهات فقط"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"عدم الإزعاج"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"البلوتوث."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"تفعيل البلوتوث."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"تم ضبط المنبّه على <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -209,6 +217,7 @@
<string name="dessert_case" msgid="9104973640704357717">"حالة الحلويات"</string>
<string name="start_dreams" msgid="9131802557946276718">"شاشة الاستراحة"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"عدم الإزعاج"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"لا يتوفر أي أجهزة مقترنة"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -360,6 +369,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"الإشعارات"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ليس هناك أي اشعارات"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
@@ -503,6 +513,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;الحالة:&lt;/b&gt; تم خفض الترتيب"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل."</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة."</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل، وتقاطع ميزة \"عدم الإزعاج\"."</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة لمقاطعة ميزة \"عدم الإزعاج\"."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"الأولوية"</string>
<string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"يتعذّر تعديل هذه الإشعارات."</string>
@@ -586,6 +598,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‏الرسائل القصيرة SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"الموسيقى"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"التقويم"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"عدم الإزعاج"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"اختصار أزرار مستوى الصوت"</string>
<string name="battery" msgid="769686279459897127">"البطارية"</string>
<string name="headset" msgid="4485892374984466437">"سماعة الرأس"</string>
@@ -704,6 +717,10 @@
<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"</string>
<string name="bt_is_off" msgid="7436344904889461591">"تم إيقاف البلوتوث."</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"تم إيقاف وضع \"عدم الإزعاج\""</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"التطبيقات التي تعمل في الخلفية"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"هل تريد إيقاف بيانات الجوّال؟"</string>
@@ -728,6 +745,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(العمل)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"المكالمات الهاتفية"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(من خلال <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"الكاميرا"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"الموقع"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"الميكروفون"</string>
@@ -830,6 +849,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غير متّصل)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"لا يمكن التبديل. انقر لإعادة المحاولة."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
<string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
@@ -863,6 +884,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"عرض أحدث الرسائل والمكالمات الفائتة والتغييرات في الحالة"</string>
<string name="people_tile_title" msgid="6589377493334871272">"محادثة"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"تم إيقاف الإشعار مؤقتًا من خلال ميزة \"عدم الإزعاج\""</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"تم إرسال رسالة من <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"تم إرسال صورة من <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"تم تعديل حالة <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -905,8 +927,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> تطبيق نشط</item>
<item quantity="one">تطبيق واحد (<xliff:g id="COUNT_0">%s</xliff:g>) نشط</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"معلومات جديدة"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"# تطبيق نشط"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"إيقاف"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقّف"</string>
@@ -914,14 +935,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"تم النسخ."</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"من <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"إغلاق واجهة مستخدم النسخ"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"تعديل النص المنسوخ"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"تعديل الصورة المنسوخة"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"الإرسال إلى جهاز مجاور"</string>
+ <string name="add" msgid="81036585205287996">"إضافة"</string>
+ <string name="manage_users" msgid="1823875311934643849">"إدارة المستخدمين"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"لا يتيح هذا الإشعار السحب لتقسيم الشاشة."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏شبكة Wi‑Fi غير متاحة"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"وضع الأولوية"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‏تم تفعيل وضع الضيف لاستخدام \"مساعد Google\"."</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 8d8a0fb32d96..00f7790e384d 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ছিষ্টেম ইউআই"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"বেটাৰী অতি সোনকালে শেষ হ\'ব পাৰে"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"নিশ্চিত কৰিলে"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যৱহাৰ কৰক"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"আৰ্হি ব্যৱহাৰ কৰক"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ কৰক"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"সম্পূৰ্ণ নিৰৱতা"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"কেৱল এলাৰ্মবোৰৰ বাবে"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"অসুবিধা নিদিব"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ব্লুটুথ।"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ব্লুটুথ অন হৈ আছে।"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>ৰ বাবে এলাৰ্ম ছেট কৰা হৈছে।"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"মিষ্টান্ন ভাণ্ডাৰ"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"কোনো যোৰা লগোৱা ডিভাইচ উপলব্ধ নহয়।"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"জাননীসমূহ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"বাৰ্তালাপ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"আটাইবোৰ নীৰৱ জাননী মচক"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;স্থিতি:&lt;/b&gt; স্থান তললৈ কৰা হৈছে"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"অগ্ৰাধিকাৰ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বাৰ্তালাপৰ সুবিধাসমূহ সমৰ্থন নকৰে"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"এছএমএছ"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"অসুবিধা নিদিব"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বুটামসমূহৰ শ্বৰ্টকাট"</string>
<string name="battery" msgid="769686279459897127">"বেটাৰী"</string>
<string name="headset" msgid="4485892374984466437">"হেডছেট"</string>
@@ -684,6 +697,10 @@
<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">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ অৱস্থাত আছে"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"অসুবিধা নিদিব অফ অৱস্থাত আছে"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"অসুবিধা নিদিব-ক কোনো এপ্ (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম বা এপে অন কৰিলে।"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"নেপথ্যত চলি থকা এপসমূহ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"বেটাৰী আৰু ডেটাৰ ব্যৱহাৰৰ বিষয়ে সবিশেষ জানিবলৈ টিপক"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ম’বাইল ডেটা অফ কৰিবনে?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(কৰ্মস্থান)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফ’ন কল"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>ৰ জৰিয়তে)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"Camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"অৱস্থান"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্ৰ\'ফ\'ন"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(সংযোগ বিচ্ছিন্ন কৰা হৈছে)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"সলনি কৰিব নোৱাৰি। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
<string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"শেহতীয়া বাৰ্তা, মিছড্‌ কল আৰু স্থিতিৰ আপডে’ট চাওক"</string>
<string name="people_tile_title" msgid="6589377493334871272">"বাৰ্তালাপ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"অসুবিধা নিদিব সুবিধাটোৱে পজ কৰিছে"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>এ এটা বাৰ্তা পঠিয়াইছে: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>এ এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>ৰ এটা স্থিতিৰ আপডে’ট আছে: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> টা সক্ৰিয় এপ্‌</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> টা সক্ৰিয় এপ্‌</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"সক্ৰিয় এপ্‌"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"বন্ধ কৰক"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"বন্ধ হ’ল"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"প্ৰতিলিপি কৰা পাঠ সম্পাদনা কৰক"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"প্ৰতিলিপি কৰা প্ৰতিচ্ছবি সম্পাদনা কৰক"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"নিকটৱৰ্তী ডিভাইচলৈ পঠাওক"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"যোগ দিয়ক"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"এই জাননীটোৱে টানি আনি এৰাৰ পৰা বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ৱাই-ফাই উপলব্ধ নহয়"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"অগ্ৰাধিকাৰ ম’ড"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantৰ অতিথি ম’ড সক্ষম কৰা হৈছে"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 1fc28a88d390..a1956b30c54c 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistemin İstifadə İnterfeysi"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batareya tezliklə bitə bilər"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> qalır"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB vasitəsilə enerji yığa bilməz"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Cihazla verilən adapterdən istifadə edin"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Üz doğrulandı"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Təsdiqləndi"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN istifadə edin"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Model istifadə edin"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Qapadın"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"tam sakitlik"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"bildirişlər"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Narahat Etməyin."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktiv."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm <xliff:g id="TIME">%s</xliff:g> üçün qurulub."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Desert Qabı"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekran qoruyucu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Narahat etməyin"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Heç bir cütlənmiş cihaz əlçatan deyil"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirişlər"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Səssiz bildirişlərin hamısını silin"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Aşağı sıraya keçirilib"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, Narahat Etməyin rejimini kəsir"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür, Narahat Etməyin rejimini kəsir"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqi"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Təqvim"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Narahat Etməyin"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Səs düymələri qısayolu"</string>
<string name="battery" msgid="769686279459897127">"Batareya"</string>
<string name="headset" msgid="4485892374984466437">"Qulaqlıq"</string>
@@ -684,6 +697,10 @@
<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 deaktivdir"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth deaktivdir"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"Narahat Etməyin\" deaktivdir"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) avtomatik qaydası tərəfindən aktiv edildi."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) tətbiqi tərəfindən aktiv edildi."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"Narahat etməyin\" rejimi avtomatik qayda və ya tətbiq tərəfindən aktiv edildi."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Arxa fonda işləyən tətbiqlər"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil data söndürülsün?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(iş)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon zəngi"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> vasitəsilə)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"məkan"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kəsildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Dəyişmək olmur. Yenidən cəhd etmək üçün toxunun."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Cihaz əlavə edin"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
<string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Son mesajlar, buraxılmış zənglər və status güncəlləmələrinə baxın"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Söhbət"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\"Narahat Etməyin\" rejimini tərəfindən durdurulub"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mesaj göndərdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> şəkil göndərdi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> status güncəlləməsi edib: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiv tətbiq</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv tətbiq</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni məlumat"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiv tətbiqlər"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dayandırın"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dayandırılıb"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Mənbə: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI kopyalanmasını qapadın"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanmış mətni redaktə edin"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanmış şəkli redaktə edin"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaxınlıqdakı cihaza göndərin"</string>
+ <string name="add" msgid="81036585205287996">"Əlavə edin"</string>
+ <string name="manage_users" msgid="1823875311934643849">"İstifadəçiləri idarə edin"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildiriş Ayrılmış ekrana sürüşdürməyi dəstəkləmir."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi əlçatan deyil"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritet rejimi"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistent qonaq rejimi aktivdir"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 555b477770a4..2019e9dbcb8a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterija će se možda uskoro isprazniti"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Još <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Punjenje preko USB-a nije uspelo"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je uključen."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen za <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrina sa poslasticama"</string>
<string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nije dostupan nijedan upareni uređaj"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Rangirano niže"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, prekida režim Ne uznemiravaj"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za jačinu zvuka"</string>
<string name="battery" msgid="769686279459897127">"Baterija"</string>
<string name="headset" msgid="4485892374984466437">"Naglavne slušalice"</string>
@@ -689,6 +702,10 @@
<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">"WiFi je isključen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Režim Ne uznemiravaj je isključen"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije pokrenute u pozadini"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite da isključite mobilne podatke?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(preko: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Konverzacija"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirano režimom Ne uznemiravaj"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
@@ -893,14 +914,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano je"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog interfejsa"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Izmenite kopirani tekst"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Izmenite kopiranu sliku"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
+ <string name="add" msgid="81036585205287996">"Dodaj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Omogućen je režim gosta u Pomoćniku"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 744600740be6..c10a36d66373 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Інтэрфейс сістэмы"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Акумулятар хутка разрадзіцца"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Засталося <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Не ўдалося выканаць зарадку праз USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Выкарыстоўвайце зараднае прыстасаванне з камплекта прылады"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Твар распазнаны"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Пацверджана"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Увесці PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Выкарыстаць узор разблакіроўкі"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыць"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"поўная цішыня"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"толькі будзільнікі"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не турбаваць."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth уключаны."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Наладжаны будзiльнiк: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Вітрына з дэсертамі"</string>
<string name="start_dreams" msgid="9131802557946276718">"Экранная застаўка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбаваць"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Няма даступных спалучаных прылад"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Апавяшчэнні"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Размовы"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Выдаліць усе апавяшчэнні без гуку"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Апавяшчэнняў няма"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем бацькоў"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Стан:&lt;/b&gt; Ацэнена як няважнае"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З\'яўляецца ўверсе раздзела размоў і паказвае на экране блакіроўкі відарыс профілю"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З\'яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое паказвае на экране блакіроўкі відарыс профілю"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З\'яўляецца ўверсе раздзела размоў, перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З\'яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Прыярытэт"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Гэтыя апавяшчэнні нельга змяніць."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-паведамленні"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Каляндар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбаваць"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Доступ праз кнопкі рэгулявання гучнасці"</string>
<string name="battery" msgid="769686279459897127">"Акумулятар"</string>
<string name="headset" msgid="4485892374984466437">"Гарнітура"</string>
@@ -694,6 +707,10 @@
<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 выключаны"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth выключаны"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Рэжым \"Не турбаваць\" выключаны"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Праграмы, якія працуюць у фонавым рэжыме"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Выключыць мабільную перадачу даных?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(працоўная)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Тэлефонны выклік"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(праз праграму \"<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>\")"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"геалакацыя"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"мікрафон"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(адключана)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не ўдалося пераключыцца. Дакраніцеся, каб паўтарыць спробу."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
<string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Глядзець нядаўнія паведамленні, прапушчаныя выклікі і абнаўленні стану"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Размова"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Прыпынена функцыяй \"Не турбаваць\""</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> прыслаў паведамленне: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў відарыс"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> абнавіў стан: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> актыўных праграм</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> актыўнай праграмы</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая інфармацыя"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Актыўныя праграмы"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Спыніць"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Спынена"</string>
@@ -900,14 +921,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скапіравана"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"З праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыць інтэрфейс капіравання"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Змяніць скапіраваны тэкст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Змяніць скапіраваны відарыс"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Адправіць на прыладу паблізу"</string>
+ <string name="add" msgid="81036585205287996">"Дадаць"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Кіраванне карыстальнікамі"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Гэта апавяшчэнне нельга перацягнуць на падзелены экран."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сетка Wi‑Fi недаступная"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Прыярытэтны рэжым"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Гасцявы рэжым для Памочніка ўключаны"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f7a1ad65b0f0..a10750401a05 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Системен ПИ"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батерията може скоро да се изтощи"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Остава/т <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Зареждането през USB не е възможно"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Използвайте оригиналното зарядно устройство"</string>
@@ -111,7 +116,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<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_qr_code_scanner_button" msgid="7521277927692910795">"Скенер за QR кодове"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Отключване"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е удостоверено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потвърдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Докоснете „Потвърждаване“ за завършване"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Използване на ПИН"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Използване на фигура"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Затваряне"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"пълна тишина"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само будилници"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не безпокойте."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Функцията за Bluetooth е включена."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Будилникът е навит за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Витрина с десерти"</string>
<string name="start_dreams" msgid="9131802557946276718">"Скрийнсейвър"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не безпокойте"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Няма налични сдвоени устройства"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известия"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Изчистване на всички беззвучни известия"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Няма известия"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Това устройство се управлява от родителя ви"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Състояние:&lt;/b&gt; Класирано по-ниско"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, прекъсва режима „Не безпокойте“"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче, прекъсва режима „Не безпокойте“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Тези известия не могат да бъдат променяни."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не безпокойте"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Пряк път към бутоните за силата на звука"</string>
<string name="battery" msgid="769686279459897127">"Батерия"</string>
<string name="headset" msgid="4485892374984466437">"Слушалки"</string>
@@ -684,6 +697,10 @@
<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 е изключена"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Функцията за Bluetooth е изключена"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Режимът „Не безпокойте“ е изключен"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режимът „Не безпокойте“ бе включен от автоматично правило (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режимът „Не безпокойте“ бе включен от приложение (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режимът „Не безпокойте“ бе включен от автоматично правило или от приложение."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Приложения, работещи на заден план"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Да се изключат ли мобилните данни?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(служебно)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонно обаждане"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(чрез <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камерата"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"местополож."</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофона"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(връзката е прекратена)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не може да се превключи. Докоснете за нов опит."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Над <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Преглеждайте скорошни съобщения, пропуснати обаждания и информация за състоянието"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Поставено на пауза от режима „Не безпокойте“"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> изпрати съобщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> изпрати изображение"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има актуализация на състоянието: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> активни приложения</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> активно приложение</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова информация"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни приложения"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Спиране"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Спряно"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"От <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отхвърляне на ПИ за копиране"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редактиране на копирания текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редактиране на копираното изображение"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Изпращане до устройство в близост"</string>
+ <string name="add" msgid="81036585205287996">"Добавяне"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Управление на потребителите"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Това известие не поддържа плъзгане за разделяне на екрана."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi не е налице"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Режимът на гост за Асистент е активиран"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 36a5bc48b2b4..b5040e959a34 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"সিস্টেম UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"চার্জ শীঘ্রই শেষ হয়ে যেতে পারে"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> অবশিষ্ট আছে"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"ইউএসবি দিয়ে চার্জ করা যাবে না"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ডিভাইসের সাথে যে চার্জারটি পেয়েছেন, সেটি ব্যবহার করুন"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ফেস যাচাই করা হয়েছে"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যবহার করুন"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"প্যাটার্ন ব্যবহার করুন"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ করুন"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"সম্পূর্ণ নীরব"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"শুধুমাত্র অ্যালার্ম"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"বিরক্ত করবে না।"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ব্লুটুথ"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ব্লুটুথ চালু আছে।"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> এ অ্যালার্ম সেট করা হয়েছে৷"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ডেজার্ট কেস"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"চেনা কোনও ডিভাইস নেই"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"বিজ্ঞপ্তি"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"কথোপকথন"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো বিজ্ঞপ্তি নেই"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;স্ট্যাটাস:&lt;/b&gt; র‍্যাঙ্ক কমে গেছে"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায়"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"অগ্রাধিকার"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"বিরক্ত করবে না"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বোতামের শর্টকাট"</string>
<string name="battery" msgid="769686279459897127">"ব্যাটারি"</string>
<string name="headset" msgid="4485892374984466437">"হেডসেট"</string>
@@ -684,6 +697,10 @@
<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">"ওয়াই ফাই বন্ধ আছে"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ বন্ধ আছে"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"বিরক্ত করবে না বিকল্পটি বন্ধ আছে"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"বিরক্ত করবে না বিকল্পটি একটি অ্যাপ <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম বা অ্যাপের দ্বারা চালু করা হয়েছে।"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"পটভূমিতে অ্যাপ চালু আছে"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"মোবাইল ডেটা বন্ধ করবেন?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(অফিস)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফোন কল"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-এর সাহায্যে)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ক্যামেরা"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"লোকেশন"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্রোফোন"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ডিসকানেক্ট হয়ে গেছে)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"পাল্টানো যাচ্ছে না। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
<string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"সাম্প্রতিক মেসেজ, মিসড কল এবং স্ট্যাটাস সংক্রান্ত আপডেট দেখুন"</string>
<string name="people_tile_title" msgid="6589377493334871272">"কথোপকথন"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'বিরক্ত করবে না\' মোডের মাধ্যমে পজ করা আছে"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> একটি মেসেজ পাঠিয়েছেন: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> একটি ছবি পাঠিয়েছেন"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> একটি স্ট্যাটাস আপডেট করেছেন: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g>টি অ্যাক্টিভ অ্যাপ</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g>টি অ্যাক্টিভ অ্যাপ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"অ্যাক্টিভ অ্যাপ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"বন্ধ করুন"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"থামানো হয়েছে"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"কপি করা টেক্সট এডিট করুন"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"কপি করা ছবি এডিট করুন"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"আশেপাশের ডিভাইসে পাঠান"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"যোগ করুন"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ব্যবহারকারীদের ম্যানেজ করুন"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"স্প্লিটস্ক্রিন মোডে এই বিজ্ঞপ্তি টেনে আনা যাবে না।"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ওয়াই-ফাই উপলভ্য নেই"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"প্রায়োরিটি মোড"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant-এর \'অতিথি মোড\' চালু করা হয়েছে"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 1545c43aafbd..b0691fe6b5b0 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistemski UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterija će se uskoro isprazniti"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
@@ -111,7 +116,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<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 kôda"</string>
+ <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Otključaj"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je provjereno"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da završite"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristi PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristi uzorak"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne ometaj."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth uključen."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Slika sa desertima"</string>
<string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne ometaj"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nema dostupnih uparenih uređaja"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavještenja"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; je rangiran niže"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, prekida funkciju Ne ometaj"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić, prekida funkciju Ne ometaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne ometaj"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za Jačinu zvuka"</string>
<string name="battery" msgid="769686279459897127">"Baterija"</string>
<string name="headset" msgid="4485892374984466437">"Slušalice s mikrofonom"</string>
@@ -689,10 +702,14 @@
<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">"WiFi veza je isključena"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Način rada Ne ometaj je isključen"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način rada Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način rada Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije koje rade u pozadini"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti prijenos podataka na mobilnoj mreži?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi mreže."</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi-ja."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"vaš operater"</string>
<string name="touch_filtered_warning" msgid="8119511393338714836">"Postavke ne mogu potvrditi vaš odgovor jer aplikacija zaklanja zahtjev za odobrenje."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Dozvoliti aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(putem aplikacije <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije moguće prebaciti. Dodirnite da pokušate ponovo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Pregledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala je funkcija Ne ometaj"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> je ažurirao/la status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
@@ -896,8 +917,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Dodaj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obavještenje ne podržava prevlačenje na podijeljeni ekran."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi je nedostupan"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Način rada Prioriteti"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Način rada za gosta Asistenta je omogućen"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 621f5f9a5383..da4cba76a427 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"IU del sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"És possible que la bateria s\'esgoti aviat"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g>."</string>
<string name="invalid_charger_title" msgid="938685362320735167">"No es pot carregar per USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Fes servir el carregador original del dispositiu"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirma per completar"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilitza el PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilitza el patró"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Tanca"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silenci total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"només alarmes"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No molestis."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activat."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"S\'ha configurat l\'alarma (<xliff:g id="TIME">%s</xliff:g>)."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Capsa de postres"</string>
<string name="start_dreams" msgid="9131802557946276718">"Estalvi de pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestis"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hi ha dispositius vinculats disponibles"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacions"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estat&lt;/b&gt;: s\'ha classificat amb un nivell inferior"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, interromp el mode No molestis"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla, interromp el mode No molestis"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritat"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestis"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Drecera per als botons de volum"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Auriculars"</string>
@@ -684,6 +697,10 @@
<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">"La Wi-Fi està desactivada"</string>
<string name="bt_is_off" msgid="7436344904889461591">"El Bluetooth està desactivat"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"El mode No molestis està desactivat"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automàtica (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicació (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una regla automàtica o una aplicació han activat el mode No molestis."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicacions que s\'estan executant en segon pla"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vols desactivar les dades mòbils?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(feina)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Trucada"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"càmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicació"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micròfon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconnectat)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No es pot canviar. Torna-ho a provar."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Consulta els missatges recents, les trucades perdudes i les actualitzacions d\'estat"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Posat en pausa pel mode No molestis"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat un missatge: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat una imatge"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> té una actualització d\'estat: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacions actives</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicació activa</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informació nova"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacions actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Atura"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Aturada"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"S\'ha copiat"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora la IU de còpia"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edita el text que has copiat"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edita la imatge que has copiat"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envia a un dispositiu proper"</string>
+ <string name="add" msgid="81036585205287996">"Afegeix"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gestiona els usuaris"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Aquesta notificació no es pot arrossegar a la pantalla dividida."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritat"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode de convidat de l\'Assistent activat"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ba976883136f..e93fc2937913 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI systému"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterie se brzy vybije"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Zbývá <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nabíjení přes USB nefunguje"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Používejte originální nabíječku, která byla dodána spolu se zařízením."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Obličej byl ověřen"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrzeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ověření dokončíte klepnutím na Potvrdit"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použít kód PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použít gesto"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zavřít"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"úplné ticho"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"pouze budíky"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nerušit."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Rozhraní Bluetooth je zapnuto."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Budík je nastaven na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Pult se sladkostmi"</string>
<string name="start_dreams" msgid="9131802557946276718">"Spořič obrazovky"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nerušit"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nejsou dostupná žádná spárovaná zařízení"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Oznámení"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazat všechna tichá oznámení"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Oznámení jsou pozastavena režimem Nerušit"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stav:&lt;/b&gt; zařazeno níže"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, deaktivuje režim Nerušit"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny a deaktivuje režim Nerušit"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendář"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nerušit"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Zkratka tlačítek hlasitosti"</string>
<string name="battery" msgid="769686279459897127">"Baterie"</string>
<string name="headset" msgid="4485892374984466437">"Sluchátka"</string>
@@ -694,6 +707,10 @@
<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 je vypnuta"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je vypnuto"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Režim Nerušit je vypnut"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim Nerušit byl zapnut automatickým pravidlem (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim Nerušit byl zapnut aplikací (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim Nerušit byl zapnut automatickým pravidlem nebo aplikací."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikace běžící na pozadí"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vypnout mobilní data?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(práce)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonní hovor"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prostřednictvím aplikace <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojeno)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nelze přepnout. Klepnutím opakujte akci."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
<string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Zobrazit poslední zprávy, zmeškané hovory a aktualizace stavu"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Konverzace"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastaveno funkcí Nerušit"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> posílá zprávu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> posílá obrázek"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizaci stavu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivních aplikací</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktivních aplikací</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informace"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivní aplikace"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Konec"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastaveno"</string>
@@ -900,14 +921,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Zkopírováno"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Z aplikace <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zavřít uživatelské rozhraní kopírování"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Upravit zkopírovaný text"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upravit zkopírovaný obrázek"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odeslat do zařízení v okolí"</string>
+ <string name="add" msgid="81036585205287996">"Přidat"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Správa uživatelů"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"U Asistenta je aktivován režim hosta"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index bbcb9bc0b530..bf460fe05c6b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Enheden løber muligvis snart tør for batteri"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> tilbage"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Enheden kan ikke oplades via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Brug den oplader, der fulgte med din enhed"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansigtet er godkendt"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekræftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tryk på Bekræft for at udføre"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Brug pinkode"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Brug mønster"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Luk"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total stilhed"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"kun alarmer"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Forstyr ikke."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth er slået til."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmen er indstillet til <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessertcase"</string>
<string name="start_dreams" msgid="9131802557946276718">"Pauseskærm"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Forstyr ikke"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Der er ingen tilgængelige parrede enheder"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikationer"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ryd alle lydløse notifikationer"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikationer er sat på pause af Forstyr ikke"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Placeret lavere"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Afbryder Forstyr ikke"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble, der afbryder Forstyr ikke"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Forstyr ikke"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Genvej til lydstyrkeknapper"</string>
<string name="battery" msgid="769686279459897127">"Batteri"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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 er slået fra"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er slået fra"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Forstyr ikke er slået fra"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tilstanden Forstyr ikke blev aktiveret af en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel eller en app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps, der kører i baggrunden"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tryk for at se info om batteri- og dataforbrug"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du deaktivere mobildata?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(arbejde)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonopkald"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameraet"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokation"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonen"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(afbrudt)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Det var ikke muligt at skifte. Tryk for at prøve igen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
<string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Se dine seneste beskeder, mistede opkald og statusopdateringer"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Sat på pause af Forstyr ikke"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en besked: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et billede"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har opdateret sin status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktiv app</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive apps</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nye oplysninger"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppet"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopieret"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Luk brugerfladen for kopi"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger kopieret tekst"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger kopieret billede"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til enhed i nærheden"</string>
+ <string name="add" msgid="81036585205287996">"Tilføj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Administrer brugere"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Denne notifikation kan ikke trækkes til en opdelt skærm."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Ingen tilgængelig Wi-Fi-forbindelse"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tilstanden Prioritet"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gæstetilstand i Assistent er aktiveret"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2b9f725e24e4..6197b3fbae0c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Der Akku ist fast leer"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Aufladen über USB nicht möglich"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Verwende das mit dem Gerät gelieferte Ladegerät"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesicht authentifiziert"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bestätigt"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN verwenden"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Muster verwenden"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Schließen"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"lautlos"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"nur Weckrufe"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Bitte nicht stören."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktiviert"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wecker gestellt für <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessertbehälter"</string>
<string name="start_dreams" msgid="9131802557946276718">"Bildschirmschoner"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bitte nicht stören"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Keine gekoppelten Geräte verfügbar"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle lautlosen Benachrichtigungen löschen"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Benachrichtigungen durch „Bitte nicht stören“ pausiert"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status&lt;/b&gt;: niedriger eingestuft"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, unterbricht „Bitte nicht stören“"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble, unterbricht „Bitte nicht stören“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorität"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bitte nicht stören"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Tastenkombination für Lautstärketasten"</string>
<string name="battery" msgid="769686279459897127">"Akku"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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">"WLAN ist deaktiviert"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ist deaktiviert"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"„Bitte nicht stören“ ist deaktiviert"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„Bitte nicht stören“ wurde von einer automatischen Regel aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„Bitte nicht stören“ wurde von einer App aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„Bitte nicht stören“ wurde von einer automatischen Regel oder einer App aktiviert."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps, die im Hintergrund ausgeführt werden"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Für Details zur Akku- und Datennutzung tippen"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobile Daten deaktivieren?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(geschäftlich)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonanruf"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(über <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"Kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"Standort"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"Mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nicht verbunden)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Wechseln nicht möglich. Tippe, um es noch einmal zu versuchen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
<string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Letzte Nachrichten, verpasste Anrufe und Statusaktualisierungen ansehen"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Unterhaltung"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Durch „Bitte nicht stören“ pausiert"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> hat eine Nachricht gesendet: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> hat ein Bild gesendet"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> hat den Status aktualisiert: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive Apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktive App</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Neue Informationen"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive Apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Beenden"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Beendet"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Von <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopieren-Benutzeroberfläche schließen"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopierten Text bearbeiten"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopiertes Bild bearbeiten"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"An Gerät in der Nähe senden"</string>
+ <string name="add" msgid="81036585205287996">"Hinzufügen"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Nutzer verwalten"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Diese Benachrichtigung lässt sich nicht auf einen geteilten Bildschirm ziehen."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant-Gastmodus aktiviert"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 609674929af5..dc0d98bc7caf 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI συστήματ."</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Η μπαταρία μπορεί να εξαντληθεί σύντομα"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Απομένουν <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Δεν είναι δυνατή η φόρτιση μέσω USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Χρησιμοποιήστε τον φορτιστή που συνοδεύει τη συσκευή σας"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Επιβεβαιώθηκε"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Χρήση PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Χρήση μοτίβου"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Κλείσιμο"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"πλήρης σίγαση"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"μόνο ξυπνητήρια"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Μην ενοχλείτε."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Ενεργό Bluetooth."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Το ξυπνητήρι έχει οριστεί στις <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Επιδόρπιο"</string>
<string name="start_dreams" msgid="9131802557946276718">"Προφύλαξη οθόνης"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Μην ενοχλείτε"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Δεν υπάρχουν διαθέσιμες συσκευές σε σύζευξη"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ειδοποιήσεις"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Συζητήσεις"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Διαγραφή όλων των ειδοποιήσεων σε σίγαση"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Κατάσταση:&lt;/b&gt; Κατατάχθηκε χαμηλότερα"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Προτεραιότητα"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Μουσική"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ημερολόγιο"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Μην ενοχλείτε"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Συντόμευση κουμπιών έντασης ήχου"</string>
<string name="battery" msgid="769686279459897127">"Μπαταρία"</string>
<string name="headset" msgid="4485892374984466437">"Ακουστικά"</string>
@@ -684,6 +697,10 @@
<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 είναι ανενεργό"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Το Bluetooth είναι ανενεργό"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Η λειτουργία \"Μην ενοχλείτε\" είναι ανενεργή"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από μια εφαρμογή (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα ή μια εφαρμογή."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Απενεργοποίηση δεδομένων κινητής τηλεφωνίας;"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(εργασία)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Τηλεφωνική κλήση"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(μέσω <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"κάμερα"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"τοποθεσία"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"μικρόφωνο"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(αποσυνδέθηκε)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Δεν είναι δυνατή η εναλλαγή. Πατήστε για επανάληψη."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
<string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Δείτε πρόσφατα μηνύματα, αναπάντητες κλήσεις και ενημερώσεις κατάστασης"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Συνομιλία"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Σε παύση από τη λειτουργία Μην ενοχλείτε"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε ένα μήνυμα: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε μια εικόνα"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έχει μια ενημέρωση κατάστασης: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ενεργές εφαρμογές</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ενεργή εφαρμογή</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Νέες πληροφορίες"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ενεργές εφαρμογές"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Διακοπή"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Διακόπηκε"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Αντιγράφηκε"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Από <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Παράβλεψη διεπαφής χρήστη αντιγραφής"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Επεξεργασία αντιγραμμένου κειμένου"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Επεξεργασία αντιγραμμένης εικόνας"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Αποστολή σε κοντινή συσκευή"</string>
+ <string name="add" msgid="81036585205287996">"Προσθήκη"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Διαχείριση χρηστών"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Αυτή η ειδοποίηση δεν υποστηρίζει τη μεταφορά με σύρσιμο για χρήση του διαχωρισμού οθόνης."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Το Wi‑Fi δεν είναι διαθέσιμο"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Λειτουργία προτεραιότητας"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Η λειτουργία επισκέπτη του Βοηθού ενεργοποιήθηκε"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f6dc3145bc9c..fcbe0a6927aa 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</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_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>
@@ -128,6 +130,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
<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_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>
@@ -205,6 +210,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
<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>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
<string name="battery" msgid="769686279459897127">"Battery"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
<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>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
<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>
@@ -708,6 +722,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
<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_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>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
@@ -889,8 +907,18 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
- <!-- no translation found for add (81036585205287996) -->
+ <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>
+ <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
<skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
<skip />
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 0b4e00945337..2e6514a3f77d 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</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_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>
@@ -128,6 +130,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
<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_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>
@@ -205,6 +210,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
<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>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
<string name="battery" msgid="769686279459897127">"Battery"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
<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>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
<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>
@@ -708,6 +722,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
<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_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>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
@@ -889,8 +907,18 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
- <!-- no translation found for add (81036585205287996) -->
+ <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>
+ <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
<skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
<skip />
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f6dc3145bc9c..fcbe0a6927aa 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</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_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>
@@ -128,6 +130,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
<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_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>
@@ -205,6 +210,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
<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>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
<string name="battery" msgid="769686279459897127">"Battery"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
<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>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
<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>
@@ -708,6 +722,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
<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_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>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
@@ -889,8 +907,18 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
- <!-- no translation found for add (81036585205287996) -->
+ <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>
+ <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
<skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
<skip />
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f6dc3145bc9c..fcbe0a6927aa 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</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_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>
@@ -128,6 +130,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
<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_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>
@@ -205,6 +210,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
<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>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
<string name="battery" msgid="769686279459897127">"Battery"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
<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>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
<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>
@@ -708,6 +722,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
<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_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>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
@@ -889,8 +907,18 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
- <!-- no translation found for add (81036585205287996) -->
+ <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>
+ <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
<skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
<skip />
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 18d87f3f6208..f05e75b187e4 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎System UI‎‏‎‎‏‎"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎Battery may run out soon‎‏‎‎‏‎"</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_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>
@@ -128,6 +130,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎Face authenticated‎‏‎‎‏‎"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎Confirmed‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎Use PIN‎‏‎‎‏‎"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎Use pattern‎‏‎‎‏‎"</string>
@@ -181,6 +185,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎Close‎‏‎‎‏‎"</string>
<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_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>
@@ -205,6 +210,7 @@
<string name="dessert_case" msgid="9104973640704357717">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎Dessert Case‎‏‎‎‏‎"</string>
<string name="start_dreams" msgid="9131802557946276718">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎Screen saver‎‏‎‎‏‎"</string>
<string name="ethernet_label" msgid="2203544727007463351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎Ethernet‎‏‎‎‏‎"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎Do Not Disturb‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎Bluetooth‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎No paired devices available‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
@@ -348,6 +354,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎Notifications‎‏‎‎‏‎"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎Conversations‎‏‎‎‏‎"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎Clear all silent notifications‎‏‎‎‏‎"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎Notifications paused by Do Not Disturb‎‏‎‎‏‎"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎Start now‎‏‎‎‏‎"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‎No notifications‎‏‎‎‏‎"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎This device is managed by your parent‎‏‎‎‏‎"</string>
@@ -491,6 +498,8 @@
<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>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb‎‏‎‎‏‎"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎Priority‎‏‎‎‏‎"</string>
<string name="no_shortcut" msgid="8257177117568230126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ doesn’t support conversation features‎‏‎‎‏‎"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
@@ -566,6 +575,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎SMS‎‏‎‎‏‎"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎Music‎‏‎‎‏‎"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎Calendar‎‏‎‎‏‎"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎Do Not Disturb‎‏‎‎‏‎"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎Volume buttons shortcut‎‏‎‎‏‎"</string>
<string name="battery" msgid="769686279459897127">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎Battery‎‏‎‎‏‎"</string>
<string name="headset" msgid="4485892374984466437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‎Headset‎‏‎‎‏‎"</string>
@@ -684,6 +694,10 @@
<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>
+ <string name="dnd_is_off" msgid="3185706903793094463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎Do Not Disturb is off‎‏‎‎‏‎"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎Do Not Disturb was turned on by an automatic rule (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎Do Not Disturb was turned on by an app (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎Do Not Disturb was turned on by an automatic rule or app.‎‏‎‎‏‎"</string>
<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>
@@ -708,6 +722,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎(work)‎‏‎‎‏‎"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎Phone call‎‏‎‎‏‎"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎(through ‎‏‎‎‏‏‎<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎(‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎(‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎camera‎‏‎‎‏‎"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎location‎‏‎‎‏‎"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎microphone‎‏‎‎‏‎"</string>
@@ -806,6 +822,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎(disconnected)‎‏‎‎‏‎"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎Can\'t switch. Tap to try again.‎‏‎‎‏‎"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎To cast this session, please open the app.‎‏‎‎‏‎"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎Unknown app‎‏‎‎‏‎"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
<string name="basic_status" msgid="2315371112182658176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎Open conversation‎‏‎‎‏‎"</string>
@@ -839,6 +857,7 @@
<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_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>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ sent an image‎‏‎‎‏‎"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has a status update: ‎‏‎‎‏‏‎<xliff:g id="STATUS">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -890,4 +909,11 @@
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎Send to nearby device‎‏‎‎‏‎"</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 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>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎Assistant guest mode enabled‎‏‎‎‏‎"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3f1cc42f880b..4363ce9c298f 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"IU del sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Es posible que pronto se agote la batería"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería."</string>
<string name="invalid_charger_title" msgid="938685362320735167">"No se puede cargar mediante USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Usa el cargador que se incluyó con el dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Se autenticó el rostro"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Presiona Confirmar para completar"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo alarmas"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No interrumpir."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
<string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No interrumpir"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos sincronizados disponibles"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; Se clasificó en una posición inferior"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"No se pueden modificar estas notificaciones."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No interrumpir"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Combinación de teclas de botones de volumen"</string>
<string name="battery" msgid="769686279459897127">"Batería"</string>
<string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
<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 desactivado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps que se ejecutan en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"¿Deseas desactivar los datos móviles?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabajo)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se pudo conectar. Presiona para volver a intentarlo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> o más"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Consulta mensajes recientes, llamadas perdidas y actualizaciones de estado"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Se detuvo por el modo No interrumpir"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> envió un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> envió una imagen"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> actualizó su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps activas</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app activa</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nueva información"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Se copió"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Descartar la copia de la IU"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar el texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar la imagen copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivos cercanos"</string>
+ <string name="add" msgid="81036585205287996">"Agregar"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Administrar usuarios"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no admite arrastrar entre pantallas divididas."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"La red Wi-Fi no está disponible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioridad"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Se habilitó el Modo de Invitado de Asistente"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b84ed6512bdb..0e7be44a61e0 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI del sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Puede que te quedes sin batería pronto"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"No se puede cargar por USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utiliza el cargador original incluido con el dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar la acción"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo alarmas"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No molestar."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"La alarma sonará a la(s) <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
<string name="start_dreams" msgid="9131802557946276718">"Salvapantallas"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestar"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos vinculados disponibles"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo No molestar"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; posición más baja"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, y aparece como burbuja"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, e interrumpe el modo No molestar"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, aparece como burbuja e interrumpe el modo No molestar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestar"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Combinación de teclas para los botones de volumen"</string>
<string name="battery" msgid="769686279459897127">"Batería"</string>
<string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
<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 desactivado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"No molestar está desactivado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automática (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicación (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una aplicación o una regla automática han activado No molestar."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicaciones que se están ejecutando en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"¿Desactivar datos móviles?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabajo)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se puede cambiar. Toca para volver a intentarlo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Emparejar nuevo dispositivo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Consulta los mensajes recientes, las llamadas perdidas y los cambios de estado"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado por No molestar"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado una imagen"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha cambiado su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicaciones activas</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Información nueva"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicaciones activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Cerrar la interfaz de copia"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagen copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo cercano"</string>
+ <string name="add" msgid="81036585205287996">"Añadir"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gestionar usuarios"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no se puede arrastrar a la pantalla dividida."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioritario"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo invitado del asistente habilitado"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 91250c384eb3..0c9d46ed868e 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Süsteemi UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Aku võib peagi tühjaks saada"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Jäänud on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Ei saa USB kaudu laadida"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Kasutage seadmega kaasas olnud laadijat"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Nägu on autenditud"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kinnitatud"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Kasuta PIN-koodi"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Kasuta mustrit"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Sulgemine"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"täielik vaikus"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ainult alarmid"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Mitte segada."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on sees."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Määratud äratus: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Maiustusekorv"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekraanisäästja"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mitte segada"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ühtegi seotud seadet pole saadaval"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Märguanded"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kustuta kõik hääletud märguanded"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Režiim Mitte segada peatas märguanded"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Olek:&lt;/b&gt; määrati madalam prioriteet"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Kuvatakse vestluste märguannete ülaosas ja profiilipildina lukustuskuval"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Kuvatakse vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muusika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mitte segada"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Helitugevuse nuppude otsetee"</string>
<string name="battery" msgid="769686279459897127">"Aku"</string>
<string name="headset" msgid="4485892374984466437">"Peakomplekt"</string>
@@ -684,6 +697,10 @@
<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">"WiFi on välja lülitatud"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth on välja lülitatud"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Funktsioon Mitte segada on välja lülitatud"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaatne reegel (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rakendus (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaatne reegel või rakendus lülitas funktsiooni Mitte segada sisse."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Rakendusi käitatakse taustal"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Kas lülitada mobiilne andmeside välja?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(töö)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonikõne"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(rakenduse <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> kaudu)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kaamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"asukoht"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ühendus on katkestatud)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ei saa lülitada. Puudutage uuesti proovimiseks."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
<string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Vaadake hiljutisi sõnumeid, vastamata kõnesid ja olekuvärskendusi"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Vestlus"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Peatas režiim Mitte segada"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> saatis sõnumi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> saatis pildi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> värskendas olekut: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiivset rakendust</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiivne rakendus</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uus teave"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiivsed rakendused"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Peata"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Peatatud"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopeeritud"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Rakendusest <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Koopiast loobumise kasutajaliides"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muuda kopeeritud teksti"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muuda kopeeritud pilti"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Saada läheduses olevasse seadmesse"</string>
+ <string name="add" msgid="81036585205287996">"Lisa"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Kasutajate haldamine"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"See märguanne ei toeta jagatud ekraanikuvale lohistamist."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi pole saadaval"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režiim Prioriteetne"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistendi külalisrežiim on lubatud"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b531794dc7a9..90d24e507ba2 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistemaren interfazea"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Laster agortuko da bateria"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> gelditzen da"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Ezin da USB bidez kargatu"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Erabili gailuaren kargagailua"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autentifikatu da aurpegia"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Erabili PINa"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Erabili eredua"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Itxi"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"isiltasun osoa"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmak soilik"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ez molestatzeko modua."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth-a."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bidezko konexioa aktibatuta dago."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma ordu honetarako ezarri da: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Postreen kutxa"</string>
<string name="start_dreams" msgid="9131802557946276718">"Pantaila-babeslea"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ez molestatzeko modua"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth-a"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ez dago parekatutako gailurik erabilgarri"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Jakinarazpenak"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"Mailaz jaitsi da &lt;b&gt;egoera:&lt;/b&gt;"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, eta ez molestatzeko modua eteten du"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean, eta ez molestatzeko modua eteten du"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Lehentasuna"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMSak"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ez molestatzeko modua"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Bolumen-botoietarako lasterbidea"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Mikrofonodun entzungailua"</string>
@@ -684,6 +697,10 @@
<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 konexioa desaktibatuta dago"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth bidezko konexioa desaktibatuta dago"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Ez molestatzeko modua desaktibatuta dago"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ez molestatzeko modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ez molestatzeko modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ez molestatzeko modua aktibatu du arau automatiko edo aplikazio batek."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikazioak abian dira atzeko planoan"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Datu-konexioa desaktibatu nahi duzu?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(lanekoa)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono-deia"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> aplikazioaren bidez)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"kokapena"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonoa"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deskonektatuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ezin da aldatu. Berriro saiatzeko, sakatu hau."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
<string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Ikusi azken mezuak, dei galduak eta egoerari buruzko informazio eguneratua"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Elkarrizketa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Ez molestatzeko moduak pausatu du"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak mezu bat bidali du: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak irudi bat bidali du"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak egoera eguneratu du: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikazio aktibo</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikazio aktibo</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informazio berria"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktibo dauden aplikazioak"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Gelditu"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Geldituta"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiatu da"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Jatorria: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopiatutako UIa baztertzeko botoia"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editatu kopiatutako testua"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editatu kopiatutako irudia"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Bidali inguruko gailu batera"</string>
+ <string name="add" msgid="81036585205287996">"Gehitu"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Kudeatu erabiltzaileak"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Jakinarazpen hau ezin da arrastatu pantaila zatitura."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi-konexioa ez dago erabilgarri"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Lehentasun modua"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Laguntzailea zerbitzuaren gonbidatu modua gaituta dago"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 642a82635396..99e214b77fe2 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"میانای کاربر سیستم"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ممکن است باتری به‌زودی تمام شود"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی مانده است"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"‏ازطریق USB شارژ نمی‌شود"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"از شارژر ارائه‌شده با دستگاه استفاده کنید"</string>
@@ -111,7 +116,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"تلفن"</string>
<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_qr_code_scanner_button" msgid="7521277927692910795">"کدخوان پاسخ‌سریع"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"باز کردن قفل"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالت‌سنجی شد"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استفاده از پین"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استفاده از الگو"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"بستن"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"سکوت کامل"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"فقط زنگ ساعت"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"مزاحم نشوید."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"بلوتوث."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"بلوتوث روشن است."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"زنگ برای <xliff:g id="TIME">%s</xliff:g> تنظیم شد."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ویترین دسر"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"هیچ دستگاه مرتبط شده‌ای موجود نیست"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اعلان‌ها"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"مکالمه‌ها"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"پاک کردن همه اعلان‌های بی‌صدا"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"اعلانی موجود نیست"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"این دستگاه را ولی‌تان مدیریت می‌کند"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;وضعیت:&lt;/b&gt; در رده‌بندی پایین‌تری قرار گرفت"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"اولویت"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگی‌های مکالمه پشتیبانی نمی‌کند"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"این اعلان‌ها قابل اصلاح نیستند."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"پیامک"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"تقویم"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"مزاحم نشوید"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"میان‌بر دکمه‌های صدا"</string>
<string name="battery" msgid="769686279459897127">"باتری"</string>
<string name="headset" msgid="4485892374984466437">"هدست"</string>
@@ -684,6 +697,10 @@
<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 خاموش است"</string>
<string name="bt_is_off" msgid="7436344904889461591">"بلوتوث خاموش است"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"«مزاحم نشوید» خاموش است"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"قانون خودکاری (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"برنامه‌ای (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"برنامه یا قانون خودکاری، «مزاحم نشوید» را روشن کرد."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"برنامه‌هایی که در پس‌زمینه اجرا می‌شوند"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"داده تلفن همراه خاموش شود؟"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(کاری)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"تماس تلفنی"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ازطریق <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"دوربین"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"مکان"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"میکروفون"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد ضربه بزنید."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
<string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"بیش‌از <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"دیدن به‌روزرسانی‌های وضعیت، تماس‌های بی‌پاسخ، و پیام‌های اخیر"</string>
<string name="people_tile_title" msgid="6589377493334871272">"مکالمه"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"با «مزاحم نشوید» موقتاً متوقف شده است"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> پیامی ارسال کرد: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> تصویری ارسال کرد"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> وضعیتش را به‌روزرسانی کرد: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"اطلاعات جدید"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامه‌های فعال"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"توقف"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقف شد"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کپی شد"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"از <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"رد کردن رابط کاربری کپی کردن"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپی‌شده"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپی‌شده"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string>
+ <string name="add" msgid="81036585205287996">"افزودن"</string>
+ <string name="manage_users" msgid="1823875311934643849">"مدیریت کاربران"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"این اعلان از تنظیم کشیدن برای دو نیمه کردن صفحه پشتیبانی نمی‌کند."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi دردسترس نیست"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"حالت اولویت"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"«حالت مهمان» «دستیار» فعال شد"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a9c11bce0360..5aca1cea9f7c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Käyttöliitt."</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Akku voi loppua pian"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> jäljellä"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Lataaminen USB:llä ei onnistu"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Käytä laitteesi mukana tullutta laturia"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Kasvot tunnistettu"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Vahvistettu"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Valitse lopuksi Vahvista"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Käytä PIN-koodia"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Käytä kuviota"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Sulje"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"hiljennä kaikki"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"vain herätykset"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Älä häiritse."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on päällä."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Hälytys asetettu, aika: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Jälkiruokavitriini"</string>
<string name="start_dreams" msgid="9131802557946276718">"Näytönsäästäjä"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Älä häiritse"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Laitepareja ei ole käytettävissä"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ilmoitukset"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Tila:&lt;/b&gt; valittu vähemmän tärkeäksi"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, keskeyttää Älä häiritse ‑tilan"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana, keskeyttää Älä häiritse ‑tilan"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Tekstiviesti"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiikki"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenteri"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Älä häiritse"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Äänenvoimakkuuspainikkeiden pikanäppäin"</string>
<string name="battery" msgid="769686279459897127">"Akku"</string>
<string name="headset" msgid="4485892374984466437">"Kuulokemikrofoni"</string>
@@ -679,11 +692,15 @@
<string name="instant_apps_message_with_help" msgid="1816952263531203932">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string>
<string name="app_info" msgid="5153758994129963243">"Sovelluksen tiedot"</string>
<string name="go_to_web" msgid="636673528981366511">"Siirry selaimeen"</string>
- <string name="mobile_data" msgid="4564407557775397216">"Mobiilitiedonsiirto"</string>
+ <string name="mobile_data" msgid="4564407557775397216">"Mobiilidata"</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 on pois päältä"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ei ole käytössä"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Älä häiritse ‑tila on pois päältä"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaattinen sääntö otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Sovellus otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaattinen sääntö tai sovellus otti käyttöön Älä häiritse ‑tilan."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Sovelluksia käynnissä taustalla"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Laitetaanko mobiilidata pois päältä?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(työ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Puhelu"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kautta: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"sijainti"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoni"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(yhteys katkaistu)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Vaihtaminen ei onnistunut. Yritä uudelleen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
<string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Yli <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Katso viimeaikaiset viestit, vastaamattomat puhelut ja tilapäivitykset"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Keskustelu"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Älä häiritse ‑tilan keskeyttämä"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> lähetti viestin: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> lähetti kuvan"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> on päivittänyt tilansa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiivista sovellusta</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiivinen sovellus</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uutta tietoa"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiiviset sovellukset"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Lopeta"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Pysäytetty"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopioitu"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Lähde: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hylkää kopioitu UI"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muokkaa kopioitua tekstiä"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muokkaa kopioitua kuvaa"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Lähetä lähellä olevaan laitteeseen"</string>
+ <string name="add" msgid="81036585205287996">"Lisää"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Ylläpidä käyttäjiä"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ilmoitus ei tue jaetulle näytölle vetämistä."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ei ole saatavilla"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tärkeät-tila"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantin vierastila käytössä"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 3ee8efa56019..1a599b5ecaf7 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"IU système"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"La pile sera bientôt épuisée"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restants"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Impossible de charger l\'appareil par USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Servez-vous du chargeur fourni avec votre appareil"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Touchez Confirmer pour terminer"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un NIP"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"aucune interruption"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmes seulement"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne pas déranger."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activé."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
<string name="start_dreams" msgid="9131802557946276718">"Écran de veille"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun des appareils associés n\'est disponible"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;État :&lt;/b&gt; abaissé d\'un niveau"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, interrompt le mode Ne pas déranger"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle, interrompt le mode Ne pas déranger"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Message texte"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
<string name="battery" msgid="769686279459897127">"Pile"</string>
<string name="headset" msgid="4485892374984466437">"Écouteurs"</string>
@@ -684,6 +697,10 @@
<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">"Le Wi-Fi est désactivé"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Le Bluetooth est désactivé"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Applications qui fonctionnent en arrière-plan"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données cellulaires?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(travail)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(par l\'intermédiaire de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
<string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Affichez les messages récents, les appels manqués et les mises à jour d\'état"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Interrompue par la fonctionnalité Ne pas déranger"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son état : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> application active</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applications actives</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelle information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applications actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"À partir de <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorer la copie de l\'IU"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string>
+ <string name="add" msgid="81036585205287996">"Ajouter"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Cette notification ne prend pas en charge le partage d\'écran par glissement."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi non disponible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode priorité"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Invité de l\'assistant activé"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 0af35baae386..1465bdbc508b 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Interface"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"La batterie est bientôt épuisée"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restants"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Impossible de recharger via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utiliser le chargeur d\'origine fourni avec votre appareil"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Appuyez sur \"Confirmer\" pour terminer"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un code PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"aucune interruption"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmes uniquement"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne pas déranger."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activé."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
<string name="start_dreams" msgid="9131802557946276718">"Économiseur d\'écran"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun appareil associé disponible."</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;État ::&lt;/b&gt; Abaissée d\'un niveau"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, apparaît sous forme de bulle"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, interrompt le mode Ne pas déranger"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, apparaît sous forme de bulle, interrompt le mode Ne pas déranger"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec les fonctionnalités de conversation"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossible de modifier ces notifications."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
<string name="battery" msgid="769686279459897127">"Batterie"</string>
<string name="headset" msgid="4485892374984466437">"Casque"</string>
@@ -684,6 +697,10 @@
<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 désactivé"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth désactivé"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Mode \"Ne pas déranger\" désactivé"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode \"Ne pas déranger\" a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode \"Ne pas déranger\" a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode \"Ne pas déranger\" a été activé par une règle automatique ou une application."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Applications en cours d\'exécution en arrière-plan"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données mobiles ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(travail)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"l\'appareil photo"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"la position"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"le micro"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Impossible de changer. Appuyez pour réessayer."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Voir les messages récents, les appels manqués et les notifications d\'état"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Mise en pause par Ne pas déranger"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son statut : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> appli active</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applis actives</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelles informations"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Désactiver l\'interface de copie"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string>
+ <string name="add" msgid="81036585205287996">"Ajouter"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Impossible de faire glisser cette notification vers l\'écran partagé."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritaire"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Invité activé pour l\'Assistant"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 81efcb54769b..5faa3df65171 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"IU do sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"A batería pode esgotarse en breve"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restante"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Non se puido realizar a carga por USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utiliza o cargador que incluía o dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autenticouse a cara"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar o proceso"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrón"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Pechar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"só alarmas"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Modo Non molestar."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma definida para as <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Caixa de sobremesa"</string>
<string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non molestar"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Non hai dispositivos vinculados dispoñibles"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacións"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borra todas as notificacións silenciadas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"O modo Non molestar puxo en pausa as notificacións"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; clasificouse nun nivel inferior"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, e aparece como unha burbulla"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, e interrompe o modo Non molestar"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, aparece como unha burbulla e interrompe o modo Non molestar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non molestar"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Atallo dos botóns de volume"</string>
<string name="battery" msgid="769686279459897127">"Batería"</string>
<string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
<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">"A wifi está desactivada"</string>
<string name="bt_is_off" msgid="7436344904889461591">"O Bluetooth está desactivado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"O modo Non molestar está desactivado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Unha norma automática (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Unha aplicación (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Unha aplicación ou norma automática activou o modo Non molestar."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicacións que se executan en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca para obter información sobre o uso de datos e a batería"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Queres desactivar os datos móbiles?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(traballo)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada de teléfono"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(mediante <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"a cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"a localiz."</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"o micrófono"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non se puido realizar o cambio. Toca para tentalo de novo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Consulta as mensaxes recentes, as chamadas perdidas e as actualizacións dos estados"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Púxose en pausa debido ao modo Non molestar"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha mensaxe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha imaxe"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> cambiou de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacións activas</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova información"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacións activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Deter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detida"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiouse"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar interface de copia"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imaxe copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo próximo"</string>
+ <string name="add" msgid="81036585205287996">"Engadir"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Xestionar usuarios"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación non pode arrastrarse á pantalla dividida."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"O modo Convidados do Asistente está activado"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 98510d5012f6..763d39de4913 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"સિસ્ટમ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"બૅટરી ટૂંક સમયમાં સમાપ્ત થશે"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> બાકી"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB મારફતે ચાર્જ કરી શકતા નથી"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"તમારા ઉપકરણ સાથે આવેલ ચાર્જરનો ઉપયોગ કરો"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ચહેરાનું પ્રમાણીકરણ થયું"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"પિનનો ઉપયોગ કરો"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"પૅટર્નનો ઉપયોગ કરો"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"બંધ કરો"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"બિલકુલ અવાજ નહીં"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"માત્ર અલાર્મ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ખલેલ પાડશો નહીં."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"બ્લૂટૂથ."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"બ્લૂટૂથ ચાલુ."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> માટે એલાર્મ સેટ કર્યું."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ડેઝર્ટ કેસ"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"કોઈ જોડી કરેલ ઉપકરણો ઉપલબ્ધ નથી"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"નોટિફિકેશન"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"વાતચીત"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"કોઈ નોટિફિકેશન નથી"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;સ્ટેટસ:&lt;/b&gt; નીચલી રેંક આપવામાં આવી"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"પ્રાધાન્યતા"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"સંગીત"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ખલેલ પાડશો નહીં"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"વૉલ્યૂમ બટન્સ શૉર્ટકટ"</string>
<string name="battery" msgid="769686279459897127">"બૅટરી"</string>
<string name="headset" msgid="4485892374984466437">"હૅડસેટ"</string>
@@ -684,6 +697,10 @@
<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">"વાઇ-ફાઇ બંધ છે"</string>
<string name="bt_is_off" msgid="7436344904889461591">"બ્લૂટૂથ બંધ છે"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"ખલેલ પાડશો નહીં બંધ છે"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ અથવા ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"મોબાઇલ ડેટા બંધ કરીએ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ઑફિસ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ફોન કૉલ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> મારફતે)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"માઇક્રોફોન"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ડિસ્કનેક્ટ કરેલું)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"સ્વિચ કરી શકતા નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
<string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના સંદેશા, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"વાતચીત"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'ખલેલ પાડશો નહીં\'ની સુવિધા દ્વારા થોભાવેલું"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ સંદેશ મોકલવામાં આવ્યો: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ છબી મોકલવામાં આવી"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા નવી સ્ટેટસ અપડેટ પોસ્ટ કરવામાં આવી: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> સક્રિય ઍપ</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> સક્રિય ઍપ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"રોકો"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"બંધ કરેલી છે"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"કૉપિ કરવામાં આવી"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>માંથી"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"\'UI | યૂઝર ઇન્ટરફેસ (UI) કૉપિ કરો\'ને છોડી દો"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"કૉપિ કરેલી ટેક્સ્ટમાં ફેરફાર કરો"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"કૉપિ કરેલી છબીમાં ફેરફાર કરો"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"નજીકના ડિવાઇસને મોકલો"</string>
+ <string name="add" msgid="81036585205287996">"ઉમેરો"</string>
+ <string name="manage_users" msgid="1823875311934643849">"વપરાશકર્તાઓને મેનેજ કરો"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"આ નોટિફિકેશન તેને સ્પ્લિટસ્ક્રીનમાં ખેંચવાની સુવિધાને સપોર્ટ કરતું નથી."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"પ્રાધાન્યતા મોડ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant અતિથિ મોડ ચાલુ કર્યો"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 2631f550d459..27e5091cdc59 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"सिस्‍टम यूआई"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"बैटरी जल्दी ही खत्म हो जाएगी"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> शेष"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"यूएसबी के ज़रिए चार्ज नहीं किया जा सकता"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"अपने डिवाइस के साथ मिलने वाले चार्जर का इस्तेमाल करें"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरे की पुष्टि हो गई"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन इस्तेमाल करें"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पैटर्न इस्तेमाल करें"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करें"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"कोई आवाज़ सुनाई नहीं देगी"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"सिर्फ़ अलार्म की आवाज़ सुनाई देगी"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"परेशान न करें."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लूटूथ."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ चालू है."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> के लिए अलार्म सेट किया गया."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"मिठाई का डिब्बा"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोई भी युग्मित डिवाइस उपलब्ध नहीं"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; रैंकिंग में नीचे किया गया"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"यह कई तरीकों से दिखती है, जैसे कि लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर और बातचीत वाली सूचनाओं में सबसे ऊपर"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"यह कई तरीकों से दिखती है, जैसे कि लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर और बातचीत वाली सूचनाओं में सबसे ऊपर. साथ ही, इसकी वजह से, \'परेशान न करें\' सुविधा में भी रुकावट आती है"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर. साथ ही, इसकी वजह से, \'परेशान न करें\' सुविधा में भी रुकावट आती है"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"मैसेज (एसएमएस) करें"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"परेशान न करें"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"वॉल्यूम बटन का शॉर्टकट"</string>
<string name="battery" msgid="769686279459897127">"बैटरी"</string>
<string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
<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">"वाई-फ़ाई बंद है"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद है"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"परेशान न करें बंद है"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"एक ऑटोमैटिक नियम (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"एक ऐप्लिकेशन (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"एक ऑटोमैटिक नियम या ऐप्लिकेशन ने परेशान न करें को चालू कर दिया था."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"बैटरी और डेटा खर्च की जानकारी के लिए छूएं"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा बंद करना चाहते हैं?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ऑफ़िस)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फ़ोन कॉल"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> की मदद से)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"कैमरा"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"जगह"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफ़ोन"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिसकनेक्ट हो गया)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच नहीं किया जा सकता. फिर से कोशिश करने के लिए टैप करें."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
<string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"हाल के मैसेज, मिस्ड कॉल, और स्टेटस अपडेट देखें"</string>
<string name="people_tile_title" msgid="6589377493334871272">"बातचीत"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'परेशान न करें\' की वजह से सूचनाएं नहीं दिख रहीं"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ने एक मैसेज भेजा है: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ने एक इमेज भेजी है"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ने स्टेटस अपडेट किया है: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ऐप्लिकेशन चालू है</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ऐप्लिकेशन चालू हैं</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"नई जानकारी"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ये ऐप्लिकेशन चालू हैं"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"बंद करें"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"रुका हुआ है"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कॉपी किया गया"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> से"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"कॉपी किया गया यूज़र इंटरफ़ेस (यूआई) खारिज करें"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी किए गए टेक्स्ट में बदलाव करें"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी की गई इमेज में बदलाव करें"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"कॉन्टेंट को आस-पास मौजूद डिवाइस पर भेजें"</string>
+ <string name="add" msgid="81036585205287996">"जोड़ें"</string>
+ <string name="manage_users" msgid="1823875311934643849">"उपयोगकर्ताओं को मैनेज करें"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"इस सूचना को स्प्लिट स्क्रीन मोड में, खींचा और छोड़ा नहीं जा सकता."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाई-फ़ाई उपलब्ध नहीं है"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant का मेहमान मोड चालू किया गया"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index da84b86547d1..d3905e7bb820 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI sustava"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterija bi se uskoro mogla isprazniti"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili s uređajem"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je autentificirano"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi za dovršetak"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentičnost provjerena"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite uzorak"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvaranje"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth uključen."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Vrijeme alarma: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Izlog za slastice"</string>
<string name="start_dreams" msgid="9131802557946276718">"Čuvar zaslona"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Upareni uređaji nisu dostupni"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavijesti"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Izbriši sve bešumne obavijesti"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavijesti"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; niže rangirana"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, prekida Ne uznemiravaj"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić, prekida Ne uznemiravaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glazba"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Prečac tipki za glasnoću"</string>
<string name="battery" msgid="769686279459897127">"Baterija"</string>
<string name="headset" msgid="4485892374984466437">"Slušalice"</string>
@@ -689,6 +702,10 @@
<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 je isključen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Način Ne uznemiravaj isključen"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Način Ne uznemiravaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način Ne uznemiravaj uključilo je automatsko pravilo ili aplikacija."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Izvođenje aplikacija u pozadini"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti mobilne podatke?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(putem apl. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nije povezano)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije prebačeno. Dodirnite da biste pokušali ponovo."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala značajka Ne uznemiravaj"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> šalje poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Korisnik <xliff:g id="NAME">%1$s</xliff:g> poslao je sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
@@ -893,14 +914,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog sučelja"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji uređaju u blizini"</string>
+ <string name="add" msgid="81036585205287996">"Dodaj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Upravljanje korisnicima"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ova obavijest ne podržava povlačenje na podijeljeni zaslon."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nije dostupan"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni način rada"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Omogućen je način rada za goste u Asistentu"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 30a5be844385..3b94d8f15d90 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Rendszer UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Az akkumulátor hamarosan lemerül"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> maradt"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nem tölthető USB-n keresztül"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Használja az eszközhöz kapott eredeti töltőt"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Arc hitelesítve"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Megerősítve"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Koppintson a Megerősítés lehetőségre"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-kód használata"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Minta használata"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Bezárás"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"teljes némítás"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"csak ébresztések"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne zavarjanak."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bekapcsolva."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Ébresztés időpontja: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Képernyővédő"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne zavarjanak"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nem áll rendelkezésre párosított eszköz"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Értesítések"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Az összes néma értesítés törlése"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Állapot:&lt;/b&gt; hátrébb sorolva"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"A beszélgetésekre vonatkozó értesítések tetején látható, és megjeleníti a profilképet a lezárási képernyőn"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, és megjeleníti a profilképet a lezárási képernyőn"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"A beszélgetésekre vonatkozó értesítések tetején látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritás"</string>
<string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-üzenetek"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Zene"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Naptár"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne zavarjanak"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"A hangerőgombok gyorsbillentyűk"</string>
<string name="battery" msgid="769686279459897127">"Akkumulátor"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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">"A Wi-Fi ki van kapcsolva"</string>
<string name="bt_is_off" msgid="7436344904889461591">"A Bluetooth ki van kapcsolva"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"A „Ne zavarjanak” mód ki van kapcsolva"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Az egyik automatikus szabály (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Az egyik alkalmazás (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Az egyik alkalmazás vagy automatikus szabály bekapcsolta a „Ne zavarjanak” módot."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"A háttérben még futnak alkalmazások"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Kikapcsolja a mobiladatokat?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(munkahely)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonhívás"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a következőn keresztül: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"helyadatok"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(leválasztva)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"A váltás nem sikerült. Próbálja újra."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
<string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Megtekintheti a legutóbbi üzeneteket, a nem fogadott hívásokat és az állapotfrissítéseket."</string>
<string name="people_tile_title" msgid="6589377493334871272">"Beszélgetés"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"A Ne zavarjanak mód által szüneteltetve"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> üzenetet küldött: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> képet küldött"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> frissítette állapotát: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktív alkalmazás</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktív alkalmazás</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Új információ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktív alkalmazások"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Leállítás"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Leállítva"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Vágólapra másolt szöveg szerkesztése"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Vágólapra másolt kép szerkesztése"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Küldés közeli eszközre"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Hozzáadás"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Felhasználók kezelése"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Az értesítés nem támogatja a megosztott képernyőre való áthúzást."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A Wi‑Fi nem áll rendelkezésre"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritás mód"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"A Segéd vendég módja engedélyezve"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 443da54eaf3d..488aa7674805 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Համակարգի ինտերֆեյս"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Մարտկոցի լիցքը շուտով կարող է սպառվել"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Մնաց <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Սարքը հնարավոր չէ լիցքավորել USB-ի միջոցով"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Օգտագործեք սարքի լիցքավորիչը"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Դեմքը ճանաչվեց"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Հաստատվեց"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ավարտելու համար հպեք «Հաստատել»"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Օգտագործել PIN կոդ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Օգտագործել նախշ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Փակել"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"կատարյալ լռություն"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"միայն զարթուցիչը"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Չանհանգստացնել։"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth:"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth-ը միացված է:"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Զարթուցիչը դրված է <xliff:g id="TIME">%s</xliff:g>-ին:"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Չանհանգստացնել"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Զուգակցված սարքեր չկան"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ծանուցումներ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Զրույցներ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ջնջել բոլոր անձայն ծանուցումները"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ծանուցումներ չկան"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Կարգավիճակը․&lt;/b&gt; կարևորության մակարդակն իջեցվել է"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Կարևոր"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը զրույցի գործառույթներ չի աջակցում"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Երաժշտություն"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Օրացույց"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Չանհանգստացնել"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Ձայնի կոճակների դյուրանցում"</string>
<string name="battery" msgid="769686279459897127">"Մարտկոց"</string>
<string name="headset" msgid="4485892374984466437">"Ականջակալ"</string>
@@ -684,6 +697,10 @@
<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-ն անջատված է"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-ն անջատված է"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Չանհանգստացնելու ռեժիմն անջատված է"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Չանհանգստացնել գործառույթը միացված է հավելվածի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կամ հավելվածի կողմից:"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Անջատե՞լ բջջային ինտերնետը"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(աշխատանքային)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Հեռախոսազանգ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(հետևյալ հավելված(ներ)ի միջոցով՝ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"տեսախցիկը"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"վայրը"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"խոսափողը"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(անջատված է)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Սխալ առաջացավ։ Հպեք՝ կրկնելու համար։"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
<string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Տեսեք վերջին հաղորդագրությունները, բաց թողնված զանգերը և կարգավիճակի մասին թարմացումները"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Զրույց"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Դադարեցվել է «Չանհանգստացնել» գործառույթի կողմից"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը հաղորդագրություն է ուղարկել. «<xliff:g id="NOTIFICATION">%2$s</xliff:g>»"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը պատկեր է ուղարկել"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը նոր կարգավիճակ է հրապարակել. «<xliff:g id="STATUS">%2$s</xliff:g>»"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ակտիվ հավելված</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ակտիվ հավելված</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Նոր տեղեկություն"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ակտիվ հավելվածներ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Դադարեցնել"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Կանգնեցված է"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Պատճենվեց"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածից"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Փակել պատճենների միջերեսը"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Փոփոխել պատճենված տեքստը"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Փոփոխել պատճենված պատկերը"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ուղարկել մոտակա սարքի"</string>
+ <string name="add" msgid="81036585205287996">"Ավելացնել"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Օգտատերերի կառավարում"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Այս ծանուցումը հնարավոր չէ քաշել տրոհված էկրանի մեկ հատվածից մյուսը։"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi-ը հասանելի չէ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Առաջնահերթության ռեժիմ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Օգնականի հյուրի ռեժիմը միացված է"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index c7339c70eb71..0913166cc1eb 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI Sistem"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterai mungkin akan segera habis"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Tidak dapat mengisi daya melalui USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Gunakan pengisi daya yang disertakan dengan perangkat"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah diautentikasi"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Dikonfirmasi"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketuk Konfirmasi untuk menyelesaikan"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan pola"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"senyap total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"hanya alarm"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Jangan Ganggu."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktif."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm disetel ke <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Etalase Hidangan Penutup"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Perangkat yang disandingkan tak tersedia"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikasi"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hapus semua notifikasi senyap"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tuamu"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Diberi Peringkat Lebih Rendah"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, mengganggu fitur Jangan Ganggu"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, mengganggu fitur Jangan Ganggu"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan tombol volume"</string>
<string name="battery" msgid="769686279459897127">"Baterai"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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 nonaktif"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth nonaktif"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Fitur Jangan Ganggu nonaktif"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Mode Jangan Ganggu diaktifkan oleh aplikasi (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis atau aplikasi."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikasi yang sedang berjalan di latar belakang"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Ketuk untuk melihat detail penggunaan baterai dan data"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Nonaktifkan data seluler?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kerja)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telepon"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(melalui <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(terputus)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
<string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Lihat pesan terbaru, panggilan tak terjawab, dan pembaruan status"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Percakapan"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh fitur Jangan Ganggu"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mengirim pesan: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> mengirim gambar"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> memposting pembaruan status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikasi aktif</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikasi aktif</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informasi baru"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikasi aktif"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Dari <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Tutup UI salin"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit gambar yang disalin"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Kirim ke perangkat di sekitar"</string>
+ <string name="add" msgid="81036585205287996">"Tambahkan"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Kelola pengguna"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Notifikasi ini tidak mendukung fitur tarik ke Layar terpisah."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi tidak tersedia"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode prioritas"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Tamu Asisten diaktifkan"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index eddd24648a7b..cddb8f81fc09 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Kerfisviðmót"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Rafhlaðan gæti tæmst bráðlega"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> eftir"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Ekki er hægt að hlaða í gegnum USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Notaðu hleðslutækið sem fylgdi tækinu þínu"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Andlit staðfest"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Staðfest"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ýttu á „Staðfesta“ til að ljúka"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Nota PIN-númer"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Nota mynstur"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Loka"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"algjör þögn"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"aðeins vekjarar"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ónáðið ekki."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Kveikt á Bluetooth."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Vekjari stilltur á <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Eftirréttaborð"</string>
<string name="start_dreams" msgid="9131802557946276718">"Skjávari"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ónáðið ekki"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Engin pöruð tæki til staðar"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Tilkynningar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hreinsa allar þöglar tilkynningar"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Staða:&lt;/b&gt; fékk lægri stöðu"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum, birtist sem blaðra"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Truflar „Ónáðið ekki“"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Birtist sem blaðra sem truflar „Ónáðið ekki“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Forgangur"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-skilaboð"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Tónlist"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Dagatal"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ónáðið ekki"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Flýtihnappar fyrir hljóðstyrk"</string>
<string name="battery" msgid="769686279459897127">"Rafhlaða"</string>
<string name="headset" msgid="4485892374984466437">"Höfuðtól"</string>
@@ -684,6 +697,10 @@
<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">"Slökkt á Wi-Fi"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Slökkt á Bluetooth"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Slökkt á „Ónáðið ekki“"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Sjálfvirk regla kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Forrit kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Sjálfvirk regla eða forrit kveikti á „Ónáðið ekki“"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Forrit sem keyra í bakgrunni"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Viltu slökkva á farsímagögnum?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(vinna)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Símtal"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(í gegnum <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"myndavél"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"staðsetning"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"hljóðnemi"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(aftengt)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ekki er hægt að skipta. Ýttu til að reyna aftur."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
<string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Sjá nýleg skilboð, ósvöruð símtöl og stöðuuppfærslur"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Samtal"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Sett í bið af „Ónáðið ekki“"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sendi skilaboð: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sendi mynd"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> er með stöðuuppfærslu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> virkt forrit</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> virk forrit</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nýjar upplýsingar"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Virk forrit"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stöðva"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stöðvað"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Afritað"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Frá <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Loka afriti notendaviðmóts"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Breyta afrituðum texta"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Breyta afritaðri mynd"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Senda í nálægt tæki"</string>
+ <string name="add" msgid="81036585205287996">"Bæta við"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Stjórna notendum"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Þessi tilkynning styður ekki að draga yfir á skiptan skjá."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi ekki tiltækt"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Forgangsstilling"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Kveikt á gestastillingu Hjálpara"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6a07f79e9e6f..ed125cd306e8 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"La batteria potrebbe esaurirsi a breve"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> rimanente"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Impossibile ricaricare tramite USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utilizza il caricabatterie fornito in dotazione con il dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Volto autenticato"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confermato"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tocca Conferma per completare"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizza PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usa sequenza"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Chiudi"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silenzio totale"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo sveglie"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Non disturbare."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth attivo."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Sveglia impostata per le <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vetrina di dolci"</string>
<string name="start_dreams" msgid="9131802557946276718">"Salvaschermo"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non disturbare"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nessun dispositivo accoppiato disponibile"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifiche"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Cancella tutte le notifiche silenziose"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stato:&lt;/b&gt; posizionata più in basso"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Appare in cima alle notifiche delle conversazioni e compare come immagine del profilo nella schermata di blocco"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Appare in cima alle notifiche delle conversazioni, nonché compare come immagine del profilo nella schermata di blocco e come bolla"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Appare in cima alle notifiche delle conversazioni, interrompe la modalità Non disturbare e compare come immagine del profilo nella schermata di blocco"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Appare in cima alle notifiche delle conversazioni, interrompe la modalità Non disturbare, nonché compare come immagine del profilo nella schermata di blocco e come bolla"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musica"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non disturbare"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Pulsanti del volume come scorciatoia"</string>
<string name="battery" msgid="769686279459897127">"Batteria"</string>
<string name="headset" msgid="4485892374984466437">"Auricolare"</string>
@@ -684,6 +697,10 @@
<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 disattivato"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth non attivo"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Funzione Non disturbare disattivata"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"La funzione Non disturbare è stata attivata da una regola automatica (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"La funzione Non disturbare è stata attivata da un\'app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"La funzione Non disturbare è stata attivata da una regola automatica o da un\'app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"App in esecuzione in background"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Disattivare i dati mobili?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(lavoro)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(tramite <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotocamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"posizione"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfono"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnesso)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non puoi cambiare. Tocca per riprovare."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
<string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Visualizza messaggi recenti, chiamate senza risposta e aggiornamenti dello stato"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversazione"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"In pausa in base alla modalità Non disturbare"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un messaggio: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un\'immagine"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha aggiornato lo stato: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,22 +899,24 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app attiva</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> app attive</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuove informazioni"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Interrompi"</string>
- <!-- no translation found for fgs_manager_app_item_stop_button_stopped_label (6950382004441263922) -->
- <skip />
+ <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Interrotta"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copia"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiato"</string>
- <!-- no translation found for clipboard_edit_source (9156488177277788029) -->
- <skip />
+ <string name="clipboard_edit_source" msgid="9156488177277788029">"Da <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora copia UI"</string>
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifica testo copiato"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifica immagine copiata"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Invia a dispositivo nelle vicinanze"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Aggiungi"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gestisci utenti"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Non è possibile trascinare questa notifica tra le due parti dello schermo diviso."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponibile"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modalità Priorità"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modalità Ospite dell\'assistente attiva"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}one{# notifica}other{# notifiche}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f959774c81ef..f88605a90adf 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ממשק משתמש של המערכת"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ייתכן שהסוללה תתרוקן בקרוב"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"‏לא ניתן לטעון באמצעות USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"שימוש במטען שסופק עם המכשיר"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"שימוש בקו ביטול נעילה"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"סגירה"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"השתקה מוחלטת"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"רק התראות"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"נא לא להפריע."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"‏Bluetooth מופעל."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ההתראה נקבעה ל-<xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"מזנון קינוחים"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"אין מכשירים מותאמים זמינים"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"התראות"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"המכשיר הזה מנוהל על ידי ההורה שלך"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;הסטטוס:&lt;/b&gt; דורג נמוך יותר"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"מוצגת בחלק העליון של קטע ההתראות וכתמונת פרופיל במסך הנעילה"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מפריעה במצב \'נא לא להפריע\'"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string>
<string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"מוזיקה"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"יומן"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"נא לא להפריע"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך ללחצני עוצמת קול"</string>
<string name="battery" msgid="769686279459897127">"סוללה"</string>
<string name="headset" msgid="4485892374984466437">"אוזניות"</string>
@@ -694,6 +707,10 @@
<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 כבוי"</string>
<string name="bt_is_off" msgid="7436344904889461591">"‏Bluetooth כבוי"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"מצב \'נא לא להפריע\' כבוי"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"אפליקציות שפועלות ברקע"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר להקיש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את חבילת הגלישה?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(עבודה)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"שיחת טלפון"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(באמצעות <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"מצלמה"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"מיקום"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"מיקרופון"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להעביר (cast) את הסשן הזה, צריך לפתוח את האפליקציה."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
<string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ההודעות האחרונות, שיחות שלא נענו ועדכוני סטטוס"</string>
<string name="people_tile_title" msgid="6589377493334871272">"שיחה"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"ההתראה הושהתה על ידי \'נא לא להפריע\'"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"התקבלה הודעה מ<xliff:g id="NAME">%1$s</xliff:g>: ‏<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה תמונה"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"הסטטוס של <xliff:g id="NAME">%1$s</xliff:g> עודכן: ‏<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> אפליקציות פעילות</item>
<item quantity="one">אפליקציה פעילה אחת (<xliff:g id="COUNT_0">%s</xliff:g>)</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"מידע חדש"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"אפליקציות פעילות"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"עצירה"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"הופסקה"</string>
@@ -900,14 +921,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"הועתק"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"המקור: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ביטול של העתקת ממשק המשתמש"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"עריכת הטקסט שהועתק"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"עריכת התמונה שהועתקה"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"שליחה למכשיר בקרבת מקום"</string>
+ <string name="add" msgid="81036585205287996">"הוספה"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ניהול משתמשים"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ההתראה הזו לא תומכת בגרירה למסך מפוצל."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi לא זמין"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‏מצב אורח ב‑Assistant מופעל"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 05ddace4a496..b946344c8af5 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"システム UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"もうすぐ電池がなくなります"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"残量が<xliff:g id="PERCENTAGE">%s</xliff:g>です"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB 経由では充電できません"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"デバイスに付属の充電器を使用してください"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"顔を認証しました"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN を使用"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"パターンを使用"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"閉じる"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"サイレント"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"アラームのみ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"サイレント モード。"</string>
<string name="accessibility_quick_settings_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">"アラームは<xliff:g id="TIME">%s</xliff:g>に設定されています。"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"デザートケース"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ペア設定されたデバイスがありません"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"会話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"サイレント通知がすべて消去されます"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"サイレント モードにより通知は一時停止中です"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"通知はありません"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"このデバイスは保護者によって管理されています"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ステータス:&lt;/b&gt; ランクが下がりました"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されます"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示されます"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示され、サイレント モードが中断されます"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示され、サイレント モードが中断されます"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>は会話機能に対応していません"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音楽"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"カレンダー"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"サイレント モード"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"音量ボタンのショートカット"</string>
<string name="battery" msgid="769686279459897127">"バッテリー"</string>
<string name="headset" msgid="4485892374984466437">"ヘッドセット"</string>
@@ -684,6 +697,10 @@
<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 は OFF です"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth は OFF です"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"サイレント モードは OFF です"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"サイレント モードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"サイレント モードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"サイレント モードが自動ルールまたはアプリによって ON になりました。"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"バックグラウンドで実行中のアプリ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"タップしてバッテリーやデータの使用量を確認"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"モバイルデータを OFF にしますか?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(業務用)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"通話"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> 経由)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"カメラ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"現在地情報"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"マイク"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(接続解除済み)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"切り替えられません。タップしてやり直してください。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
<string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> 件以上"</string>
<string name="people_tile_description" msgid="8154966188085545556">"最近のメッセージ、不在着信、最新のステータスが表示されます"</string>
<string name="people_tile_title" msgid="6589377493334871272">"会話"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"サイレント モードにより一時停止"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> さんからのメッセージ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> さんが画像を送信しました"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> さんの近況: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">有効なアプリ: <xliff:g id="COUNT_1">%s</xliff:g> 個</item>
<item quantity="one">有効なアプリ: <xliff:g id="COUNT_0">%s</xliff:g> 個</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"最新情報"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"有効なアプリ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"停止中"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"コピーしたテキストを編集"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"コピーした画像を編集"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"付近のデバイスに送信"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"追加"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ユーザーの管理"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"この通知は、分割画面へのドラッグがサポートされていません。"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi を利用できません"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先順位モード"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"アシスタント ゲストモードを有効にしました"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index cf77cacaaa3d..31d760611843 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"სისტემის UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ბატარეა შესაძლოა მალე ამოიწუროს"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"დარჩენილია <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB-თ დატენვა ვერ ხერხდება"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"გამოიყენეთ დამტენი, რომელიც თქვენს მოწყობილობას მოჰყვა"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"სახის ამოცნობილია"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"დადასტურებული"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-კოდის გამოყენება"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ნიმუშის გამოყენება"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"დახურვა"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"სრული სიჩუმე"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"მხოლოდ მაღვიძარები"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"არ შემაწუხოთ."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ჩართულია."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"მაღვიძარა დაყენებულია: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"სადესერტო ყუთი"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"დაწყვილებული მოწყობილობები მიუწვდომელია"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"შეტყობინებები"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"საუბრები"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"შეტყობინებები არ არის."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"მოწყობილობას თქვენი მშობელი მართავს"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;სტატუსი:&lt;/b&gt; ნაკლებად პრიორიტეტული"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"პრიორიტეტი"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"მუსიკა"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"კალენდარი"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"არ შემაწუხოთ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ხმის ღილაკების მალსახმობი"</string>
<string name="battery" msgid="769686279459897127">"ბატარეა"</string>
<string name="headset" msgid="4485892374984466437">"ყურსაცვამი"</string>
@@ -684,6 +697,10 @@
<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 გამორთულია"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth გამორთულია"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"„არ შემაწუხოთ“ რეჟიმი გამორთულია"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„არ შემაწუხოთ“ ჩაირთო აპის მიერ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით ან აპის მიერ."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ფონურ რეჟიმში გაშვებული აპები"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"გსურთ მობილური ინტერნეტის გამორთვა?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(სამსახური)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"სატელეფონო ზარი"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-ის მეშვეობით)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"კამერა"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"მდებარეობა"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"მიკროფონი"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(კავშირი გაწყვეტილია)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ვერ გადაირთო. შეეხეთ ხელახლა საცდელად."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
<string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ბოლოდროინდელი შეტყობინებების, გამოტოვებული ზარების და სტატუსის განახლებების ნახვა"</string>
<string name="people_tile_title" msgid="6589377493334871272">"მიმოწერა"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"დაპაუზებულია ფუნქციის „არ შემაწუხოთ“ მიერ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>-მა გაგზავნა შეტყობინება: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) სურათი გამოგზავნა"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>-მა განაახლა სტატუსი: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> აქტიური აპი</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> აქტიური აპი</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ახალი ინფორმაცია"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"აქტიური აპები"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"შეწყვეტა"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"შეწყვეტილია"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"კოპირებული ტექსტის რედაქტირება"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"კოპირებული სურათის რედაქტირება"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ახლომახლო მოწყობილობაზე გაგზავნა"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"დამატება"</string>
+ <string name="manage_users" msgid="1823875311934643849">"მომხმარებლების მართვა"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ამ შეტყობინების გადათრევა გაყოფილ ეკრანებს შორის არ არის მხარდაჭერილი."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi მიუწვდომელია"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"პრიორიტეტული რეჟიმი"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"ასისტენტის სტუმრის რეჟიმი ჩართულია"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 32d2e512f1a7..c8abf951d255 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Жүйе интерфейсі"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батерея заряды жақын арада бітуі мүмкін"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> қалды"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB арқылы зарядтау мүмкін емес"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Құрылғымен бірге берілген зарядтау құралын пайдаланыңыз"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Бет танылды."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодын пайдалану"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Өрнекті пайдалану"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Жабу"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"үнсіз"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"оятқыштар ғана"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Мазаламау."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth қосулы."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Дабыл <xliff:g id="TIME">%s</xliff:g> уақытына реттелген."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Десерт жағдайы"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Жұптасқан құрылғылар жоқ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Хабарландырулар"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Әңгімелер"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Барлық үнсіз хабарландыруларды өшіру"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Хабарландырулар Мазаламау режимінде кідіртілді"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Күйі:&lt;/b&gt; маңыздылық деңгейі төмендетілген"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті ретінде көрсетіледі."</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады."</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті ретінде көрсетіледі, Мазаламау режимін тоқтатады."</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады, Мазаламау режимін тоқтатады."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгіме функцияларын қолдамайды."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Мәтіндік хабар"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mузыка"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Күнтізбе"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Мазаламау"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Дыбыс деңгейі түймелерінің төте жолы"</string>
<string name="battery" msgid="769686279459897127">"Батарея"</string>
<string name="headset" msgid="4485892374984466437">"Құлақаспап жинағы"</string>
@@ -684,6 +697,10 @@
<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 өшірулі"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өшірулі"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Мазаламау режимі өшірулі"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) автоматты ережесі арқылы қосылды."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) қолданбасы арқылы қосылды."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Мазаламау режимі автоматты ереже немесе қолданба арқылы қосылды."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Фонда жұмыс істеп тұрған қолданбалар"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобильдік деректер өшірілсін бе?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(жұмыс)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон қоңырауы"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> арқылы)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"геодерек"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратулы)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ауысу мүмкін емес. Әрекетті қайталау үшін түртіңіз."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
<string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарларды, өткізіп алған қоңыраулар мен жаңартылған күйлерді көруге болады."</string>
<string name="people_tile_title" msgid="6589377493334871272">"Әңгіме"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Мазаламау режимі арқылы кідіртілді."</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сурет жіберді."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ағымдағы күйін жаңартты: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> белсенді қолданба</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> белсенді қолданба</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңа ақпарат"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Белсенді қолданбалар"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Тоқтату"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Тоқтатылған"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көшірілді"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасынан"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көшіру интерфейсін жабу"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көшірілген мәтінді өңдеу"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көшірілген суретті өңдеу"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Маңайдағы құрылғыға жіберу"</string>
+ <string name="add" msgid="81036585205287996">"Қосу"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Пайдаланушыларды басқару"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Бұл хабарландыруды бөлінген экранға сүйреп апару мүмкін емес."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi қолжетімсіз"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Басымдық режимі"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant қонақ режимі қосылды"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 581d3e6bc6b2..78e6c8439f12 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI ប្រព័ន្ធ"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"អាចនឹងអស់ថ្មក្នុងពេលបន្តិចទៀត"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"នៅ​សល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"មិន​អាច​សាក​តាម USB បានទេ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"សូមប្រើ​ឆ្នាំង​សាក​ដែល​ភ្ជាប់​មក​ជាមួយ​ឧបករណ៍​របស់អ្នក"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ប្រើកូដ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ប្រើ​លំនាំ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"បិទ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"បិទសំឡេង​ទាំងស្រុង"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"សំឡេងរោទ៍​ប៉ុណ្ណោះ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"កុំ​រំខាន។"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ប៊្លូធូស"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"បើក​ប៊្លូធូស។"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"កំណត់​សំឡេង​រោទ៍​សម្រាប់ <xliff:g id="TIME">%s</xliff:g> ។"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ករណី Dessert"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"មិន​មាន​ឧបករណ៍​ផ្គូផ្គង​ដែល​អាច​ប្រើ​បាន"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ការជូនដំណឹង"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ការសន្ទនា"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើម​ឥឡូវ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"គ្មាន​ការ​ជូនដំណឹង"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ស្ថានភាព៖&lt;/b&gt; បានចាត់ថ្នាក់ទាបជាងមុន"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្អាក់មុខងារកុំ​រំខាន"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ បង្អាក់មុខងារកុំ​រំខាន"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"អាទិភាព"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើ​មុខងារ​សន្ទនា​បានទេ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"សារ SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"តន្ត្រី"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ប្រតិទិន"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"កុំ​រំខាន"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ផ្លូវកាត់ប៊ូតុងកម្រិតសំឡេង"</string>
<string name="battery" msgid="769686279459897127">"ថ្ម"</string>
<string name="headset" msgid="4485892374984466437">"កាស"</string>
@@ -684,6 +697,10 @@
<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 បាន​បិទ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ប៊្លូធូស​បាន​បិទ"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"មុខងារ​កុំរំខាន​បាន​បិទ"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយកម្មវិធី (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ ឬ​កម្មវិធី។"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"បិទទិន្នន័យទូរសព្ទចល័ត?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ការងារ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ការហៅ​ទូរសព្ទ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(តាមរយៈ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"កាមេរ៉ា"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ទីតាំង"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"មីក្រូហ្វូន"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(បាន​ដាច់)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"មិនអាចប្ដូរបានទេ។ សូមចុចដើម្បី​ព្យាយាម​ម្ដងទៀត។"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
<string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"មើលព័ត៌មាន​ថ្មីៗ​អំពីស្ថានភាព ការខកខាន​ទទួល និងសារថ្មីៗ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ការ​សន្ទនា"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"បានផ្អាក​ដោយមុខងារ​កុំរំខាន"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើសារ៖ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> បាន​ផ្ញើ​រូបភាព"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> មាន​បច្ចុប្បន្នភាព​ស្ថានភាព៖ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">កម្មវិធីសកម្ម <xliff:g id="COUNT_1">%s</xliff:g></item>
<item quantity="one">កម្មវិធីសកម្ម <xliff:g id="COUNT_0">%s</xliff:g></item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ព័ត៌មានថ្មី"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"កម្មវិធីសកម្ម"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ឈប់"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"បានឈប់"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"បានចម្លង"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"ពី <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ច្រានចោល UI ចម្លង"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"កែអត្ថបទ​ដែលបានចម្លង"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"កែរូបភាព​ដែលបានចម្លង"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ផ្ញើទៅ​ឧបករណ៍​នៅជិត"</string>
+ <string name="add" msgid="81036585205287996">"បញ្ចូល"</string>
+ <string name="manage_users" msgid="1823875311934643849">"គ្រប់គ្រង​អ្នក​ប្រើប្រាស់"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ការជូនដំណឹងនេះមិនអាចឱ្យអូសដើម្បីបំបែកអេក្រង់បានទេ។"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ត្រូវបានបិទ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"មុខងារ​អាទិភាព"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់​ម៉ោងរោទ៍"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"បានបើក​មុខងារភ្ញៀវរបស់ Assistant"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f1428a0abce2..e10f5d393787 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ಸಿಸ್ಟಂ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ಬ್ಯಾಟರಿ ಸದ್ಯದಲ್ಲೇ ಖಾಲಿಯಾಗಬಹುದು"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ಉಳಿದಿದೆ"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ಮೂಲಕ ಚಾರ್ಜ್‌ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ನಿಮ್ಮ ಸಾಧನದೊಂದಿಗೆ ನೀಡಲಾಗಿರುವ ಚಾರ್ಜರ್‌ ಬಳಸಿ"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ಪಿನ್ ಬಳಸಿ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ಪ್ಯಾಟರ್ನ್ ಬಳಸಿ"</string>
@@ -176,11 +183,12 @@
<skip />
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ಅಧಿಸೂಚನೆಯ ಛಾಯೆ."</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
- <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಪರದೆ."</string>
+ <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಸ್ಕ್ರೀನ್."</string>
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಪರದೆ"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚು"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ಅಡಚಣೆ ಮಾಡಬೇಡ."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ಬ್ಲೂಟೂತ್."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> ಗಂಟೆಗೆ ಅಲಾರಮ್ ಹೊಂದಿಸಲಾಗಿದೆ."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ಡೆಸರ್ಟ್ ಕೇಸ್"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ಯಾವುದೇ ಜೋಡಿಸಲಾದ ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂಭಾಷಣೆಗಳು"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ಎಲ್ಲಾ ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ಸ್ಥಿತಿ:&lt;/b&gt; ಕಡಿಮೆ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ಆದ್ಯತೆ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್‌ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ಎಸ್ಎಂಎಸ್"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ಸಂಗೀತ"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌"</string>
<string name="battery" msgid="769686279459897127">"ಬ್ಯಾಟರಿ"</string>
<string name="headset" msgid="4485892374984466437">"ಹೆಡ್‌ಸೆಟ್"</string>
@@ -684,6 +697,10 @@
<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">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ಬ್ಲೂಟೂತ್‌ ಆಫ್ ಆಗಿದೆ"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆಫ್ ಆಗಿದೆ"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"(<xliff:g id="ID_1">%s</xliff:g>) ಸ್ವಯಂಚಾಲಿತ ನಿಯಮದ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"(<xliff:g id="ID_1">%s</xliff:g>) ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ಸ್ವಯಂಚಾಲಿತ ನಿಯಮ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ಮೊಬೈಲ್ ಡೇಟಾ ಆಫ್ ಮಾಡಬೇಕೆ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ಉದ್ಯೋಗ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ಫೋನ್ ಕರೆ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ಮೂಲಕ)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ಕ್ಯಾಮರಾ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ಸ್ಥಳ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ಮೈಕ್ರೋಫೋನ್‌"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ಬದಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
<string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ಇತ್ತೀಚಿನ ಸಂದೇಶಗಳು, ಮಿಸ್ಡ್ ಕಾಲ್‌ಗಳು ಮತ್ತು ಸ್ಥಿತಿ ಅಪ್‌ಡೇಟ್‌ಗಳು"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ಸಂಭಾಷಣೆ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ನಿಂದ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸ್ಥಿತಿಯ ಅಪ್‌ಡೇಟ್ ಹೊಂದಿದ್ದಾರೆ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ಹೊಸ ಮಾಹಿತಿ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ನಿಲ್ಲಿಸಿ"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ನಿಲ್ಲಿಸಿದೆ"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"ನಕಲಿಸಿದ ಪಠ್ಯವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"ನಕಲಿಸಿದ ಚಿತ್ರವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಿ"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"ಸೇರಿಸಿ"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡುವುದನ್ನು ಈ ಅಧಿಸೂಚನೆಯು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ಆದ್ಯತೆ ಮೋಡ್"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ಅತಿಥಿ ಮೋಡ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 02246b48d4b1..ba6ef05d7ba1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"시스템 UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"배터리가 얼마 남지 않음"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> 남았습니다."</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB로 충전할 수 없습니다."</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"기기와 함께 제공된 충전기를 사용하세요."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"얼굴이 인증되었습니다."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN 사용"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"패턴 사용"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"닫기"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"모두 음소거"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"알람만 허용"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"방해 금지 모드"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"블루투스"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"블루투스: 사용"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"알람이 <xliff:g id="TIME">%s</xliff:g>(으)로 설정되었습니다."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"디저트 케이스"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"페어링된 기기가 없습니다"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"알림"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"대화"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"무음 알림 모두 삭제"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 알림이 일시중지됨"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;상태:&lt;/b&gt; 순위 낮춤"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 방해 금지 모드를 무시함"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시, 방해 금지 모드를 무시함"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"음악"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"캘린더"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"방해 금지 모드"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"볼륨 버튼 단축키"</string>
<string name="battery" msgid="769686279459897127">"배터리"</string>
<string name="headset" msgid="4485892374984466437">"헤드셋"</string>
@@ -684,6 +697,10 @@
<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가 사용 중지됨"</string>
<string name="bt_is_off" msgid="7436344904889461591">"블루투스가 사용 중지됨"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"방해 금지 모드가 사용 중지됨"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"방해 금지 모드가 자동 규칙(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"방해 금지 모드가 앱(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"방해 금지 모드가 자동 규칙 또는 앱에 의해 사용 설정되었습니다."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"백그라운드에서 실행 중인 앱"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"탭하여 배터리 및 데이터 사용량 확인"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"모바일 데이터를 사용 중지하시겠습니까?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(직장)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"전화 통화"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> 사용)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"카메라"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"위치"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"마이크"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(연결 끊김)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"전환할 수 없습니다. 다시 시도하려면 탭하세요."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
<string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"최근 메시지, 부재중 전화, 상태 업데이트 보기"</string>
<string name="people_tile_title" msgid="6589377493334871272">"대화"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"방해 금지 모드로 인해 일시중지됨"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>님이 메시지를 보냈습니다: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>님이 이미지를 보냈습니다."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>님의 상태가 업데이트되었습니다: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">활성 상태의 앱 <xliff:g id="COUNT_1">%s</xliff:g>개</item>
<item quantity="one">활성 상태의 앱 <xliff:g id="COUNT_0">%s</xliff:g>개</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"새로운 정보"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"활성 상태의 앱"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"중지"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"중지됨"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"복사됨"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"복사한 위치: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI 복사 닫기"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"복사된 텍스트 편집"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"복사된 이미지 편집"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"근처 기기에 전송"</string>
+ <string name="add" msgid="81036585205287996">"추가"</string>
+ <string name="manage_users" msgid="1823875311934643849">"사용자 관리"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"드래그하여 화면을 분할하는 기능이 지원되지 않는 알림입니다."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi를 이용할 수 없습니다."</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"우선순위 모드입니다."</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"어시스턴트 게스트 모드가 사용 설정되었습니다."</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index c8c56caa9dea..a31ab6d3f0bf 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Тутум UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батарея жакында отуруп калышы мүмкүн"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> калды"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB аркылуу кубатталбай жатат"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Түзмөгүңүз менен келген кубаттагычты колдонуңуз"</string>
@@ -111,7 +116,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<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_qr_code_scanner_button" msgid="7521277927692910795">"QR коддорунун сканери"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Кулпусун ачуу"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Жүздүн аныктыгы текшерилди"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ырасталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодду колдонуу"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Графикалык ачкычты колдонуу"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Жабуу"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"тымтырс"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ойготкуч гана"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Тынчымды алба."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth күйүк."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Ойготкуч кийинкиге коюлган: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Десерт себети"</string>
<string name="start_dreams" msgid="9131802557946276718">"Көшөгө"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Тынчымды алба"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Жупташкан түзмөктөр жок"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Билдирмелер"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Сүйлөшүүлөр"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бардык үнсүз билдирмелерди өчүрүү"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Абалы:&lt;/b&gt; Төмөндөдү"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Сүйлөшүүлөр тууралуу билдирмелердин жогору жагында, ошондой эле кулпуланган экранда профилдин сүрөтү түрүндө көрүнөт"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнөт"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Маанилүүлүгү"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда оозеки сүйлөшкөнгө болбойт"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Жылнаама"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Тынчымды алба"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string>
<string name="battery" msgid="769686279459897127">"Батарея"</string>
<string name="headset" msgid="4485892374984466437">"Гарнитура"</string>
@@ -684,6 +697,10 @@
<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 өчүк"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өчүк"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"Тынчымды алба\" режими өчүк"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматтык эреже \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Колдонмо \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматтык эреже же колдонмо \"Тынчымды алба\" режимин күйгүздү."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Фондо иштеп жаткан колдонмолор"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобилдик Интернетти өчүрөсүзбү?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(жумуш)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон чалуу"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> аркылуу)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"жайгашкан жер"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратылды)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Которулбай жатат. Кайталоо үчүн басыңыз."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөктү жупташтыруу"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
<string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Акыркы билдирүүлөрдү, жооп берилбеген чалууларды жана статустардын жаңырганын көрөсүз"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Сүйлөшүү"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\"Тынчымды алба\" режими тындырды"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сүрөт жөнөттү"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> жаңы абалы тууралуу жарыялады: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> жигердүү колдонмо</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> жигердүү колдонмо</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңы маалымат"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Жигердүү колдонмолор"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Токтотуу"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Токтотулду"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көчүрүлдү"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосунан"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көчүрмөнү жабуу интерфейси"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көчүрүлгөн текстти түзөтүү"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көчүрүлгөн сүрөттү түзөтүү"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Жакын жердеги түзмөккө жөнөтүү"</string>
+ <string name="add" msgid="81036585205287996">"Кошуу"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Колдонуучуларды башкаруу"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Бул билдирмени бөлүнгөн экранда сүйрөөгө болбойт."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi жеткиликсиз"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Маанилүү сүйлөшүүлөр режими"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Жардамчынын конок режими иштетилди"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6b96c1a57d55..204e3d92a3a6 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ສ່ວນຕິດຕໍ່ຜູ້ໃຊ້ຂອງລະບົບ"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ແບັດເຕີຣີໃກ້ຈະໝົດແລ້ວ"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"ຍັງ​ເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"ບໍ່ສາມາດສາກຜ່ານ USB ໄດ້"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ກະລຸນາໃຊ້ຕົວສາກທີ່ມາພ້ອມກັບອຸປະກອນຂອງທ່ານ"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ຢືນຢັນແລ້ວ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ໃຊ້ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ໃຊ້ຮູບແບບ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ປິດ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ງຽບທັງໝົດ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ໂມງປຸກເທົ່ານັ້ນ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ຫ້າມລົບກວນ."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ເປີດ."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ຕັ້ງໂມງປຸກ <xliff:g id="TIME">%s</xliff:g> ແລ້ວ."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ກ່ອງຂອງຫວານ"</string>
<string name="start_dreams" msgid="9131802557946276718">"ພາບພັກໜ້າຈໍ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ຫ້າມລົບກວນ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ບໍ່​ມີ​ອຸ​ປະ​ກອນ​ທີ່​ສາ​ມາດ​ຈັບ​ຄູ່​ໄດ້"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ການແຈ້ງເຕືອນ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ການສົນທະນາ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ສະຖານະ:&lt;/b&gt; ມີອັນດັບຕ່ຳລົງແລ້ວ"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ສຳຄັນ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບຄຸນສົມບັດການສົນທະນາ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ຂໍ້ຄວາມສັ້ນ(SMS)"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ດົນຕີ"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ປະຕິທິນ"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ຫ້າມລົບກວນ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ທາງລັດປຸ່ມສຽງ"</string>
<string name="battery" msgid="769686279459897127">"ແບັດເຕີຣີ"</string>
<string name="headset" msgid="4485892374984466437">"​ຊຸດ​ຫູ​ຟັງ"</string>
@@ -684,6 +697,10 @@
<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 ປິດຢູ່"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ປິດຢູ່"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"ຫ້າມລົບກວນ ປິດຢູ່"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ມີແອັບເປີດໃຊ້ໂໝດຫ້າມລົບກວນ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ ຫຼື ແອັບໃດໜຶ່ງ."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ປິດອິນເຕີເນັດມືຖືໄວ້ບໍ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ວຽກ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ໂທລະສັບ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ຜ່ານ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ກ້ອງຖ່າຍຮູບ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ສະຖານທີ່"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ໄມໂຄຣໂຟນ"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ບໍ່ສາມາດສະຫຼັບໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
<string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ເບິ່ງຂໍ້ຄວາມຫຼ້າສຸດ, ສາຍບໍ່ໄດ້ຮັບ ແລະ ອັບເດດສະຖານະ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ການສົນທະນາ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"ຢຸດຊົ່ວຄາວແລ້ວໂດຍໂໝດຫ້າມລົບກວນ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຂໍ້ຄວາມ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຮູບພາບແລ້ວ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ອັບເດດສະຖານະ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">ແອັບທີ່ນຳໃຊ້ຢູ່ <xliff:g id="COUNT_1">%s</xliff:g> ແອັບ</item>
<item quantity="one">ແອັບທີ່ນຳໃຊ້ຢູ່ <xliff:g id="COUNT_0">%s</xliff:g> ແອັບ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ຂໍ້ມູນໃໝ່"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ແອັບທີ່ນຳໃຊ້ຢູ່"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ຢຸດ"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ຢຸດແລ້ວ"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"ແກ້ໄຂຂໍ້ຄວາມທີ່ສຳເນົາແລ້ວ"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"ແກ້ໄຂຮູບທີ່ສຳເນົາແລ້ວ"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ສົ່ງໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"ເພີ່ມ"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ຈັດການຜູ້ໃຊ້"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ການແຈ້ງເຕືອນນີ້ບໍ່ຮອງຮັບການລາກໄປໃສ່ Splitscreen."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ບໍ່ສາມາດໃຊ້ Wi‑Fi ໄດ້"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ໂໝດຄວາມສຳຄັນ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"ເປີດການນຳໃຊ້ໂໝດແຂກຜູ້ຊ່ວຍແລ້ວ"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5179ad9d3e15..6bcfa0e91678 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistemos NS"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Akumuliatoriaus energija gali netrukus išsekti"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Liko <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Negalima įkrauti naudojant USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Naudokite originalų su įrenginiu pateiktą įkroviklį"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Veidas autentifikuotas"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Patvirtinta"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Naudoti PIN kodą"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Naudoti atrakinimo piešinį"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Uždaryti"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"visiška tyla"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tik įspėjimai"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Netrukdymo režimas."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"„Bluetooth“."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"„Bluetooth“ įjungtas."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signalas nustatytas <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Desertų dėklas"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekrano užsklanda"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternetas"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Netrukdymo režimas"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nėra pasiekiamų susietų įrenginių"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pranešimai"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Išvalyti visus tylius pranešimus"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nėra įspėjimų"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Būsenos:&lt;/b&gt; reitingas sumažintas"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, burbule"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, pertraukia netrukdymo režimą"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, debesėlyje, pertraukia netrukdymo režimą"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetiniai"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ nepalaiko pokalbių funkcijų"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šių pranešimų keisti negalima."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendorius"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Netrukdymo režimas"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Garsumo mygtukų spartusis klavišas"</string>
<string name="battery" msgid="769686279459897127">"Akumuliatorius"</string>
<string name="headset" msgid="4485892374984466437">"Ausinės"</string>
@@ -694,6 +707,10 @@
<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“ išjungtas"</string>
<string name="bt_is_off" msgid="7436344904889461591">"„Bluetooth“ išjungtas"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Netrukdymo režimas išjungtas"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Netrukdymo režimą įjungė automatinė taisyklė (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Netrukdymo režimą įjungė programa (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Netrukdymo režimą įjungė automatinė taisyklė arba programa."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Programos, veikiančios fone"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Išjungti mobiliojo ryšio duomenis?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(darbas)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono skambutis"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(naud. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparatą"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vietovę"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoną"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(atjungta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nepavyko perjungti. Bandykite vėl palietę."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
<string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> +"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Peržiūrėkite naujausius pranešimus, praleistus skambučius ir būsenos atnaujinimus"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Pokalbis"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pristabdyta dėl netrukdymo režimo"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė pranešimą: „<xliff:g id="NOTIFICATION">%2$s</xliff:g>“"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė vaizdą"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atnaujino būseną: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aktyvios programos</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktyvių programų</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nauja informacija"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktyvios programos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Sustabdyti"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Sustabdyta"</string>
@@ -903,8 +924,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Redaguoti nukopijuotą tekstą"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redaguoti nukopijuotą vaizdą"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Siųsti į įrenginį netoliese"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"Pridėti"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Tvarkyti naudotojus"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Šio pranešimo vilkimas išskaidyto ekrano režimu nepalaikomas."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"„Wi‑Fi“ ryšys nepasiekiamas"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteto režimas"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Įgalintas Padėjėjo svečio režimas"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 63b6b2e01d96..286cdecc6c4b 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistēmas UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Akumulators, iespējams, drīz izlādēsies"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Atlikuši <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nevar veikt uzlādi, izmantojot USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Izmantojiet ierīces komplektācijā iekļauto lādētāju"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Seja autentificēta"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Apstiprināts"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Izmantot PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Izmantot kombināciju"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Aizvērt"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"pilnīgs klusums"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tikai signāli"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Režīms “Netraucēt”."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth savienojums ir ieslēgts."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signāls ir iestatīts uz: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Saldo ēdienu stends"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekrānsaudzētājs"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Tīkls Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režīms “Netraucēt”"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nav pieejama neviena pārī savienota ierīce."</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Paziņojumi"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Notīrīt visus klusos paziņojumus"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Statuss:&lt;/b&gt; rangs pazemināts"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā."</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis."</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, pārtrauc režīmu “Netraucēt”."</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis, pārtrauc režīmu “Netraucēt”."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritārs"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Īsziņas"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mūzika"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendārs"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režīms “Netraucēt”"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Skaļuma pogu saīsne"</string>
<string name="battery" msgid="769686279459897127">"Akumulators"</string>
<string name="headset" msgid="4485892374984466437">"Austiņas"</string>
@@ -689,6 +702,10 @@
<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 ir izslēgts"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ir izslēgts"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Režīms “Netraucēt” ir izslēgts"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režīmu “Netraucēt” ieslēdza automātiska kārtula (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režīmu “Netraucēt” ieslēdza lietotne (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režīmu “Netraucēt” ieslēdza automātiska kārtula vai lietotne."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Lietotnes, kas darbojas fonā"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vai izslēgt mobilos datus?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(darbs)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tālruņa zvans"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(izmantojot: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"atrašanās vieta"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofons"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(savienojums pārtraukts)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nevar pārslēgt. Pieskarieties, lai mēģinātu vēlreiz."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
<string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Skatiet jaunākos ziņojumus, neatbildētos zvanus un statusa atjauninājumus."</string>
<string name="people_tile_title" msgid="6589377493334871272">"Saruna"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Rādīšana pārtraukta režīma Netraucēt dēļ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja ziņojumu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja attēlu"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atjaunināja statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktīva lietotne</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktīvas lietotnes</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Jauna informācija"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktīvās lietotnes"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Apturēt"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Apturēta"</string>
@@ -893,14 +914,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nokopēts"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"No lietotnes <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Noraidīt ar kopēšanu saistīto lietotāja saskarnes elementu"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediģēt nokopēto tekstu"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediģēt nokopēto attēlu"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Sūtīt uz tuvumā esošu ierīci"</string>
+ <string name="add" msgid="81036585205287996">"Pievienot"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Pārvaldīt lietotājus"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Šis paziņojums neatbalsta vilkšanu uz dalīto ekrānu."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nav pieejams"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritātes režīms"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Asistenta viesa režīms ir iespējots"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 7642a9af994e..ffa0e58b88b5 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Кориснички интерфејс на систем"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Наскоро може да снема батерија"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Преостануваат <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Не може да се полни преку USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Користете го полначот што дојде со вашиот уред"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е проверено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користи PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користи шема"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"целосна тишина"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не вознемирувај."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth е вклучен."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм наместен за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Нема достапни спарени уреди"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерија"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известувања"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Избриши ги сите бесчујни известувања"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известувањата се паузирани од „Не вознемирувај“"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; рангирано пониско"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, го прекинува „Не вознемирувај“"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче, го прекинува „Не вознемирувај“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не вознемирувај"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Кратенка за копчињата за јачина на звук"</string>
<string name="battery" msgid="769686279459897127">"Батерија"</string>
<string name="headset" msgid="4485892374984466437">"Слушалки"</string>
@@ -684,6 +697,10 @@
<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 е исклучено"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth е исклучен"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"„Не вознемирувај“ е исклучено"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Едно автоматско правило (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Една апликација (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Едно автоматско правило или апликација ја вклучи „Не вознемирувај“."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Апликациите се извршуваат во заднина"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Допрете за детали за батеријата и потрошениот интернет"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Да се исклучи мобилниот интернет?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(службена)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски повик"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преку <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"локација"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(врската е прекината)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не се префрла. Допрете и обидете се пак."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
<string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Видете ги неодамнешните пораки, пропуштени повици и промени на статусот"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано од „Не вознемирувај“"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> испрати порака: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> испрати слика"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање на статусот: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> активна апликација</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> активни апликации</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нови информации"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни апликации"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Крај"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Запрено"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Од <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отфрли го корисничкиот интерфејс за копирање"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменете го копираниот текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменете ја копираната слика"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Испратете до уред во близина"</string>
+ <string name="add" msgid="81036585205287996">"Додај"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Управувајте со корисниците"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Известувањево не поддржува влечење на поделен екран."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi е недостапна"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Режимот на гостин за „Помошникот“ е овозможен"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 1bde5a008916..6aeb7e75e0da 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"സിസ്റ്റം UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ബാറ്ററി ഉടൻ തീർന്നേക്കാം"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB വഴി ചാർജ് ചെയ്യാനാകില്ല"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ഉപകരണത്തിനൊപ്പം ലഭിച്ച ചാർജർ ഉപയോഗിക്കുക"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"സ്ഥിരീകരിച്ചു"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"പിൻ ഉപയോഗിക്കുക"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"പാറ്റേൺ ഉപയോഗിക്കുക"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"അവസാനിപ്പിക്കുക"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"പൂർണ്ണ നിശബ്‌ദത"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"അലാറങ്ങൾ മാത്രം"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ശല്യപ്പെടുത്തരുത്."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ബ്ലൂടൂത്ത് ഓണാണ്."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>-ന് അലാറം സജ്ജീകരിച്ചു."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ഡെസേർട്ട് കെയ്സ്"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ജോടിയാക്കിയ ഉപകരണങ്ങളൊന്നും ലഭ്യമല്ല"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"അറിയിപ്പുകൾ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;നില:&lt;/b&gt; താഴ്ന്ന റാങ്കിംഗ് നൽകി"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ഒരു ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"മുൻഗണന"</string>
<string name="no_shortcut" msgid="8257177117568230126">"സംഭാഷണ ഫീച്ചറുകളെ <xliff:g id="APP_NAME">%1$s</xliff:g> പിന്തുണയ്‌ക്കുന്നില്ല"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS:"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"സംഗീതം"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ശല്യപ്പെടുത്തരുത്"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"വോളിയം ബട്ടൺ കുറുക്കുവഴി"</string>
<string name="battery" msgid="769686279459897127">"ബാറ്ററി"</string>
<string name="headset" msgid="4485892374984466437">"ഹെഡ്‌സെറ്റ്"</string>
@@ -684,6 +697,10 @@
<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">"വൈഫൈ ഓഫാണ്"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ഓഫാണ്"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\'ശല്യപ്പെടുത്തരുത്\' ഓഫാണ്"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"സ്വയമേവയുള്ള ഒരു നയം (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ഒരു ആപ്പ് (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"സ്വയമേവയുള്ള ഒരു നയമോ ആപ്പോ \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"മൊബൈൽ ഡാറ്റ ഓഫാക്കണോ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ഔദ്യോഗികം)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ഫോൺ കോൾ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> എന്നതിലൂടെ)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ക്യാമറ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ലൊക്കേഷന്‍"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"മൈക്രോഫോൺ"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(വിച്ഛേദിച്ചു)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"മാറാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
<string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"അടുത്തിടെയുള്ള സന്ദേശങ്ങൾ, മിസ്‌ഡ് കോൾ, സ്റ്റാറ്റസ് അപ്‌ഡേറ്റുകൾ എന്നിവ കാണൂ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"സംഭാഷണം"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'ശല്യപ്പെടുത്തരുത്\' ഓണായതിനാൽ തൽക്കാലം നിർത്തി"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ഒരു സന്ദേശം അയച്ചു: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>, ഒരു ചിത്രം അയച്ചു"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> എന്നയാൾ സ്‌റ്റാറ്റസ് അപ്‌ഡേറ്റ് ചെയ്‌തു: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">സജീവമായ <xliff:g id="COUNT_1">%s</xliff:g> ആപ്പുകൾ</item>
<item quantity="one">സജീവമായ <xliff:g id="COUNT_0">%s</xliff:g> ആപ്പ്</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"പുതിയ വിവരങ്ങൾ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"നിർത്തുക"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"നിർത്തി"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"പകർത്തിയ ടെക്സ്റ്റ് എഡിറ്റ് ചെയ്യുക"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"പകർത്തിയ ചിത്രം എഡിറ്റ് ചെയ്യുക"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"സമീപത്തുള്ള ഉപകരണത്തിലേക്ക് അയയ്ക്കുക"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"ചേർക്കുക"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ഉപയോക്താക്കളെ മാനേജ് ചെയ്യുക"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"സ്പ്ലിറ്റ് സ്ക്രീനിലേക്ക് വലിച്ചിടുന്നതിനെ ഈ അറിയിപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"വൈഫൈ ലഭ്യമല്ല"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"മുൻഗണനാ മോഡ്"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"സഹായി അതിഥി മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c63bd3d7d9dc..4abfe1b0bb48 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Систем UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батaрей удахгүй дуусaж болзошгүй"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> үлдсэн"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB-р цэнэглэх боломжгүй байна"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Төхөөрөмждөө дагалдаж ирсэн цэнэглэгчийг ашиглах"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Царайг баталгаажууллаа"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Баталгаажсан"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Дуусгахын тулд баталгаажуулахыг товших"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ПИН ашиглах"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Хээ ашиглах"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Хаах"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"бүх дууг хаах"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"зөвхөн сэрүүлэг"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Бүү саад бол."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth идэвхтэй."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Сэрүүлгийг <xliff:g id="TIME">%s</xliff:g>-д тохируулсан."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Амттаны хайрцаг"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Хослуулсан төхөөрөмж байхгүй"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерей"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Мэдэгдлүүд"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Харилцан яриа"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Төлөв:&lt;/b&gt; Доогуур зэрэглэл хийсэн"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Харилцан ярианы дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулна"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд Бүү саад бол горимыг тасалдуулна"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана. Бүү саад бол горимыг тасалдуулна"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Чухал"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Хөгжим"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Бүү саад бол"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Дууны түвшний товчлуурын товчлол"</string>
<string name="battery" msgid="769686279459897127">"Батарей"</string>
<string name="headset" msgid="4485892374984466437">"Чихэвч"</string>
@@ -684,6 +697,10 @@
<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 унтраалттай байна"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth унтраалттай байна"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Бүү саад бол горим унтраалттай байна"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автомат дүрэм (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Цаана ажиллаж буй апп"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобайл датаг унтраах уу?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ажил)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Утасны дуудлага"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-р)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камер"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"байршил"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(салсан)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Сэлгэх боломжгүй. Дахин оролдохын тулд товшино уу."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
<string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Саяхны мессеж, аваагүй дуудлага болон төлөвийн шинэчлэлтийг харах"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Харилцан яриа"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Бүү саад бол горимоор түр зогсоосон"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> мессеж илгээсэн: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> зураг илгээсэн"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> төлөвийн шинэчлэлт хийсэн байна: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">Идэвхтэй <xliff:g id="COUNT_1">%s</xliff:g> апп</item>
<item quantity="one">Идэвхтэй <xliff:g id="COUNT_0">%s</xliff:g> апп</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Шинэ мэдээлэл"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Идэвхтэй аппууд"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Зогсоох"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Зогсоосон"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Хуулсан текстийг засах"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Хуулсан зургийг засах"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ойролцоох төхөөрөмж рүү илгээх"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Нэмэх"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Хэрэглэгчдийг удирдах"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Энэ мэдэгдэл нь Дэлгэцийг хуваах горим руу чирэхийг дэмждэггүй."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi боломжгүй"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Чухал горим"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Туслахын зочны горимыг идэвхжүүлсэн"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fca67d2c5295..2ec0073808b2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"सिस्टीम UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"बॅटरी लवकर संपू शकते"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> शिल्लक"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB द्वारे चार्ज होऊ शकत नाही"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"तुमच्या डिव्हाइससह आलेल्या चार्जरचा वापर करा"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करा"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"संपूर्ण शांतता"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"फक्‍त अलार्म"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"व्यत्यय आणू नका."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लूटूथ."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ सुरू."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> साठी अलार्म सेट केला."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"मिष्ठान्न प्रकरण"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोणतेही जोडलेले डिव्हाइसेस उपलब्ध नाहीत"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बॅटरी"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचना"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सर्व सायलंट सूचना साफ करा"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"सूचना नाहीत"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिती&lt;/b&gt; ला थोडी कमी म्हणून रँक केले गेले"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"कॅलेंडर"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"व्यत्यय आणू नका"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"आवाजाच्या बटणांचा शार्टकट"</string>
<string name="battery" msgid="769686279459897127">"बॅटरी"</string>
<string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
<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">"वाय-फाय बंद आहे"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद आहे"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"व्यत्यय आणू नका बंद आहे"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने सुरू केले."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने सुरू केले."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने सुरू केले."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"अ‍ॅप्स बॅकग्राउंडमध्‍ये सुरू आहेत"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा बंद करायचा?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ऑफिस)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कॉल"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> द्वारे)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"मायक्रोफोन"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट केलेले)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच करू शकत नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
<string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"अलीकडील मेसेज, मिस्ड कॉल आणि स्टेटस अपडेट पहा"</string>
<string name="people_tile_title" msgid="6589377493334871272">"संभाषण"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"व्यत्यय आणू नका द्वारे थांबवले गेले"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> यांनी मेसेज पाठवला: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> यांनी इमेज पाठवली"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> यांनी स्टेटस अपडेट केले: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> अ‍ॅक्टिव्ह ॲप्स</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> अ‍ॅक्टिव्ह ॲप</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"नवीन माहिती"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"अ‍ॅक्टिव्ह ॲप्स"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"थांबवा"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"थांबवले"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी केलेला मजकूर संपादित करा"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी केलेली इमेज संपादित करा"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"जवळपासच्या डिव्हाइसवर पाठवा"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"जोडा"</string>
+ <string name="manage_users" msgid="1823875311934643849">"वापरकर्ते व्यवस्‍थापित करा"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ही सूचना स्प्लिटस्क्रीनवर ड्रॅग करण्याला सपोर्ट करत नाही."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाय-फाय उपलब्ध नाही"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राधान्य मोड"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant चा अतिथी मोड सुरू केला"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b87a79cca38e..06270d71427e 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI Sistem"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Bateri mungkin kehabisan tidak lama lagi"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> yang tinggal"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Tidak dapat mengecas melalui USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Gunakan pengecas yang disertakan dengan peranti anda"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah disahkan"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Disahkan"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketik Sahkan untuk menyelesaikan"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan corak"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"senyap sepenuhnya"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"penggera sahaja"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Jangan Ganggu."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth dihidupkan."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Penggera ditetapkan pada <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Bekas Pencuci Mulut"</string>
<string name="start_dreams" msgid="9131802557946276718">"Penyelamat skrin"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Tiada peranti berpasangan tersedia"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pemberitahuan"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tiada pemberitahuan"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Dinilai Lebih Rendah"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, mengganggu Jangan Ganggu"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung, mengganggu Jangan Ganggu"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Keutamaan"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan butang kelantangan"</string>
<string name="battery" msgid="769686279459897127">"Bateri"</string>
<string name="headset" msgid="4485892374984466437">"Set Kepala"</string>
@@ -684,6 +697,10 @@
<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 dimatikan"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth dimatikan"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Jangan Ganggu dimatikan"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Jangan Ganggu dihidupkan oleh peraturan automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Jangan Ganggu dihidupkan oleh apl (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Jangan Ganggu dihidupkan oleh peraturan automatik atau apl."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apl yang berjalan di latar belakang"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Matikan data mudah alih?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kerja)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telefon"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(melalui <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(diputuskan sambungan)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat menukar. Ketik untuk mencuba lagi."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
<string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Lihat mesej terbaharu, panggilan terlepas dan kemaskinian status"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Perbualan"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh Jangan Ganggu"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> menghantar mesej: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> menghantar imej"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> mempunyai kemaskinian status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apl aktif</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> apl aktif</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maklumat baharu"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apl aktif"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Daripada <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ketepikan penyalinan UI"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit imej yang disalin"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Hantar ke peranti berdekatan"</string>
+ <string name="add" msgid="81036585205287996">"Tambah"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Urus pengguna"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Pemberitahuan ini tidak menyokong penyeretan ke Skrin pisah."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi dimatikan"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mod keutamaan"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mod tetamu Assistant didayakan"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 0248d10fdda5..4a4f1a16f517 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"စနစ်၏ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"မကြာမီ ဘက်ထရီကုန်သွားနိုင်ပါသည်"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်ရှိနေ"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ဖြင့် အားသွင်း၍မရပါ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"သင့်စက်ပစ္စည်းနှင့် အတူပါလာသည့် အားသွင်းကိရိယာကို အသုံးပြုပါ"</string>
@@ -111,7 +116,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"ဖုန်း"</string>
<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_qr_code_scanner_button" msgid="7521277927692910795">"QR ကုဒ်ဖတ်စနစ်"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"သော့ဖွင့်ရန်"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"အတည်ပြုပြီးပြီ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ပင်နံပါတ်သုံးရန်"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ပုံစံကို သုံးရန်"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ပိတ်ရန်"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"လုံးဝ အသံပိတ်ထားရန်"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"နှိုးစက်များသာ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"မနှောင့်ယှက်ရ။"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ဘလူးတုသ်။"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ဘလူးတုသ် ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"နိုးစက်ပေးထားသော အချိန် <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"မုန့်ထည့်သော ပုံး"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ချိတ်တွဲထားသည့် ကိရိယာများ မရှိ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ဘက်ထရီ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"အကြောင်းကြားချက်များ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက်များ မရှိ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;အခြေအနေ-&lt;/b&gt; အဆင့်လျှော့ထားသည်"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြသည်"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ပူဖောင်းကွက်အဖြစ် မြင်ရသည်"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ‘မနှောင့်ယှက်ရ’ ကို ရပ်တန့်သည်"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ရပ်တန့်သည်"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ဦးစားပေး"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS စာတိုစနစ်"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ပြက္ခဒိန်"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"မနှောင့်ယှက်ရ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"အသံထိန်းချုပ်သည့်ခလုတ် ဖြတ်လမ်း"</string>
<string name="battery" msgid="769686279459897127">"ဘက်ထရီ"</string>
<string name="headset" msgid="4485892374984466437">"မိုက်ခွက်ပါနားကြပ်"</string>
@@ -684,6 +697,10 @@
<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 ပိတ်ထားသည်"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ဘလူးတုသ်ကို ပိတ်ထားသည်"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"မနှောင့်ယှက်ရ\" ကို ပိတ်ထားသည်"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်း (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"မနှောင့်ယှက်ရ\" ကို အက်ပ် (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်းတစ်ခု သို့မဟုတ် အက်ပ်တစ်ခုက ဖွင့်ခဲ့သည်။"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"မိုဘိုင်းဒေတာ ပိတ်မလား။"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(လုပ်ငန်းသုံး)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ဖုန်းခေါ်ဆိုမှု"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> မှတစ်ဆင့်)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ကင်မရာ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"တည်နေရာ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"မိုက်ခရိုဖုန်း"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ချိတ်ဆက်မှု မရှိပါ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ပြောင်း၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
<string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"မကြာသေးမီက မက်ဆေ့ဂျ်၊ လွတ်သွားသောခေါ်ဆိုမှုနှင့် အခြေအနေအပ်ဒိတ်များကို ကြည့်နိုင်သည်"</string>
<string name="people_tile_title" msgid="6589377493334871272">"စကားဝိုင်း"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"‘မနှောင့်ယှက်ရ’ ဖြင့် ခဏရပ်ထားသည်"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> က မက်ဆေ့ဂျ်ပို့လိုက်သည်- <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> က ပုံပို့လိုက်သည်"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> က အခြေအနေ အပ်ဒိတ်လုပ်လိုက်သည်- <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">ပွင့်နေသည့်အက်ပ် <xliff:g id="COUNT_1">%s</xliff:g> ခု</item>
<item quantity="one">ပွင့်နေသည့်အက်ပ် <xliff:g id="COUNT_0">%s</xliff:g> ခု</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"အချက်အလက်သစ်"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ပွင့်နေသည့်အက်ပ်များ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ရပ်ရန်"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ရပ်ထားသည်"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ကူးပြီးပါပြီ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ထံမှ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI မိတ္တူမကူးတော့ရန်"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ကူးထားသည့်စာသားကို တည်းဖြတ်ရန်"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ကူးထားသည့်ပုံကို ပြင်ဆင်ရန်"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"အနီးတစ်ဝိုက်ရှိ စက်များသို့ ပို့ရန်"</string>
+ <string name="add" msgid="81036585205287996">"ထည့်ရန်"</string>
+ <string name="manage_users" msgid="1823875311934643849">"အသုံးပြုသူများ စီမံရန်"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ဤအကြောင်းကြားချက်သည် ‘မျက်နှာပြင်ခွဲ၍ပြသမှု’ သို့ ဖိဆွဲခြင်းကို မပံ့ပိုးပါ။"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi မရပါ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ဦးစားပေးမုဒ်"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ဧည့်သည်သုံးခွင့်မုဒ် ဖွင့်ထားသည်"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 76cfef5704b1..5ccf52890432 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batteriet går kanskje snart tomt"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> gjenstår"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Kan ikke lade via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Bruk laderen som fulgte med enheten"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Bruk PIN-kode"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Bruk mønster"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Lukk"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total stillhet"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"bare alarmer"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ikke forstyrr."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth er på."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmen ble stilt for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessertmonter"</string>
<string name="start_dreams" msgid="9131802557946276718">"Skjermsparer"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ikke forstyrr"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ingen sammenkoblede enheter er tilgjengelige"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Varsler"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Fjern alle lydløse varsler"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Varsler er satt på pause av «Ikke forstyrr»"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Rangert lavere"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, avbryter «Ikke forstyrr»"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble, avbryter «Ikke forstyrr»"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musikk"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ikke forstyrr"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Hurtigtast for volumknappene"</string>
<string name="battery" msgid="769686279459897127">"Batteri"</string>
<string name="headset" msgid="4485892374984466437">"Hodetelefoner"</string>
@@ -684,6 +697,10 @@
<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 er av"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er av"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Ikke forstyrr er av"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ikke forstyrr ble slått på av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ikke forstyrr ble slått på av en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ikke forstyrr ble slått på av en automatisk regel eller en app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apper kjører i bakgrunnen"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Trykk for detaljer om batteri- og databruk"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du slå av mobildata?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(jobb)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtale"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameraet"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"posisjon"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonen"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frakoblet)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan ikke bytte. Trykk for å prøve igjen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
<string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Se nylige meldinger, tapte anrop og statusoppdateringer"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Satt på pause av «Ikke forstyrr»"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en melding: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et bilde"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har en statusoppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive apper</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny informasjon"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apper"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stopp"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppet"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Lukk kopi-UI"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger den kopierte teksten"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger det kopierte bildet"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til en enhet i nærheten"</string>
+ <string name="add" msgid="81036585205287996">"Legg til"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Administrer brukere"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Dette varselet støtter ikke at du drar det til en delt skjerm."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi er utilgjengelig"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteringsmodus"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gjestemodus for assistenten er slått på"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 158a8913071a..471bf14152d8 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"सिस्टम UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ब्याट्री चाँडै सकिन सक्छ"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> बाँकी"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB मार्फत चार्ज गर्न सकिँदैन"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"तपाईंको यन्त्रसँगै आएको चार्जर प्रयोग गर्नुहोस्‌"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"अनुहार प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN प्रयोग गर्नुहोस्"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ढाँचा प्रयोग गर्नुहोस्"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"बन्द गर्नुहोस्"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"पूर्ण मौनता"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"अलार्महरू मात्र"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"बाधा नपुऱ्याउनुहोस्।"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लुटुथ।"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लुटुथ खुला छ।"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>को लागि सङ्केत घन्टी सेट गरिएको"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"स्क्रिन सेभर"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"बाधा नपुऱ्याउनुहोस्"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लुटुथ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"जोडी उपकरणहरू उपलब्ध छैन"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कुनै सूचनाहरू छैनन्"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो डिभाइस तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; कम महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"यो वार्तालापका सूचनाहरूको सिरानमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"यो वार्तालापका सूचनाहरूको सिरानमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"सङ्गीत"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"पात्रो"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"बाधा नपुऱ्याउनुहोस्"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"भोल्युम बटनका सर्टकट"</string>
<string name="battery" msgid="769686279459897127">"ब्याट्री"</string>
<string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
<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 निष्क्रिय छ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ निष्क्रिय छ"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"कुनै स्वचालित नियम वा अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो।"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"पृष्ठभूमिमा चल्ने एपहरू"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(कार्यालय)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कल"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> मार्फत)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"क्यामेरा"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफोन"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट गरिएको छ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"बदल्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ डिभाइस कनेक्ट गर्नुहोस्"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
<string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"हालसालैका म्यासेज, मिस कल र स्ट्याटस अपडेट हेर्नुहोस्"</string>
<string name="people_tile_title" msgid="6589377493334871272">"वार्तालाप"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'बाधा नपुऱ्याउनुहोस्\' ले पज गरेको छ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा म्यासेज पठाउनुभएको छ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा फोटो पठाउनुभयो"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ले स्ट्याटस अपडेट गर्नुभएको छ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> वटा सक्रिय एप</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> सक्रिय एप</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"नयाँ जानकारी"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"सक्रिय एपहरू"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"रोक्नुहोस्"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"रोकिएको छ"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"कपी गरिएको टेक्स्ट सम्पादन गर्नुहोस्"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"कपी गरिएको फोटो सम्पादन गर्नुहोस्"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"नजिकैको डिभाइसमा पठाउनुहोस्"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"हाल्नुहोस्"</string>
+ <string name="manage_users" msgid="1823875311934643849">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"यो सूचना ड्र्याग गरेर स्प्लिटस्क्रिनमा लैजान मिल्दैन।"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi उपलब्ध छैन"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"सहायकको अतिथि मोड अन गरिएको छ"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index f85bbee74115..047f99f130b7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Systeem-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batterij is bijna leeg"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Nog <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Kan niet opladen via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Gebruik de oplader die bij je apparaat is geleverd"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gezicht geverifieerd"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestigd"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestigen om te voltooien"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Pincode gebruiken"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Patroon gebruiken"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Sluiten"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"totale stilte"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alleen wekkers"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Niet storen."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aan."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wekker is ingesteld op <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessertshowcase"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Niet storen"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen gekoppelde apparaten beschikbaar"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Meldingen"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekken"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle stille meldingen wissen"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Meldingen onderbroken door \'Niet storen\'"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen meldingen"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; lager gerangschikt"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, onderbreekt Niet storen"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel, onderbreekt Niet storen"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziek"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Niet storen"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppen als sneltoets"</string>
<string name="battery" msgid="769686279459897127">"Batterij"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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">"Wifi staat uit"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth staat uit"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Niet storen staat uit"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Niet storen is aangezet door een automatische regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Niet storen is aangezet door een app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Niet storen is aangezet door een automatische regel of app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps uitgevoerd op achtergrond"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tik voor batterij- en datagebruik"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobiele data uitzetten?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(werk)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefoongesprek"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"locatie"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfoon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(verbinding verbroken)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan niet schakelen. Tik om het opnieuw te proberen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-nummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build-nummer naar klembord gekopieerd."</string>
<string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Bekijk recente berichten, gemiste gesprekken en statusupdates"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbroken door Niet storen"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> heeft een bericht gestuurd: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> heeft een afbeelding gestuurd"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> heeft een statusupdate: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> actieve apps</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> actieve app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nieuwe informatie"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Actieve apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppen"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestopt"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Gekopieerd"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Uit <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI voor kopiëren sluiten"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Gekopieerde tekst bewerken"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Gekopieerde afbeelding bewerken"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Naar apparaat in de buurt sturen"</string>
+ <string name="add" msgid="81036585205287996">"Toevoegen"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gebruikers beheren"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Deze melding biedt geen ondersteuning voor slepen naar het gesplitste scherm."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi niet beschikbaar"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitsmodus"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gastmodus voor de Assistent staat aan"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index dab199b72aa3..0dca918eccce 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ସିଷ୍ଟମ୍ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ଖୁବ୍ ଶୀଘ୍ର ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବାକି ଅଛି"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍‌କୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ପାଟର୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ସମ୍ପୂର୍ଣ୍ଣ ନୀରବତା"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"କେବଳ ଆଲାର୍ମ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ।"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ବ୍ଲୁଟୁଥ।"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ବ୍ଲୁଟୂଥ୍‍‍ ଚାଲୁ ଅଛି।"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>ରେ ଆଲାର୍ମ ସେଟ୍‍ କରାଯାଇଛି।"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ଡେଜର୍ଟ କେସ୍‌"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ପେୟାର୍‍ ହୋଇଥିବା କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ସ୍ଥିତି:&lt;/b&gt; ରେଙ୍କ ତଳକୁ କରାଯାଇଛି"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ମ୍ୟୁଜିକ୍‍"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"କ୍ୟାଲେଣ୍ଡର୍"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ଭଲ୍ୟୁମ ବଟନ୍‍ ଶର୍ଟକଟ୍‍"</string>
<string name="battery" msgid="769686279459897127">"ବ୍ୟାଟେରୀ"</string>
<string name="headset" msgid="4485892374984466437">"ହେଡସେଟ୍‍"</string>
@@ -684,6 +697,10 @@
<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">"ୱାଇ-ଫାଇ ଅଫ୍‍ ଅଛି"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୂଥ୍‍‌ ଅଫ୍ ଅଛି"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ଅଛି"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ଏକ (<xliff:g id="ID_1">%s</xliff:g>) ନିୟମ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍‍ କରାଗଲା।"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ଏକ ଆପ୍‍ (<xliff:g id="ID_1">%s</xliff:g>) ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‌ କରାଗଲା।"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ଏକ ସ୍ୱଚାଳିତ ନିୟମ କିମ୍ବା ଆପ୍‍ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‍ କରାଗଲା।"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ବ୍ୟାକଗ୍ରାଉଣ୍ଡରେ ଆପ୍‍ ଚାଲୁଛି"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ବ୍ୟାଟେରୀ ଏବଂ ଡାଟା ବ୍ୟବହାର ଉପରେ ବିବରଣୀ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ମୋବାଇଲ୍‌ ଡାଟା ବନ୍ଦ କରିବେ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ୱାର୍କ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ଫୋନ୍ କଲ୍"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ମାଧ୍ୟମରେ)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ୍‍"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ମାଇକ୍ରୋଫୋନ୍"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ସ୍ୱିଚ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
<string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ବର୍ତ୍ତମାନର ମେସେଜ୍, ମିସ୍ଡ କଲ୍ ଏବଂ ସ୍ଥିତି ଅପଡେଟଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ବାର୍ତ୍ତାଳାପ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଦ୍ୱାରା ବିରତ କରାଯାଇଛି"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ମେସେଜ୍ ପଠାଇଛନ୍ତି: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ଛବି ପଠାଇଛନ୍ତି"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ସ୍ଥିତି ଅପଡେଟ୍ କରିଛନ୍ତି: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g>ଟି ସକ୍ରିୟ ଆପ</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g>ଟି ସକ୍ରିୟ ଆପ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ନୂଆ ସୂଚନା"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ବନ୍ଦ ହୋଇଛି"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"କପି କରାଯାଇଥିବା ଟେକ୍ସଟକୁ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"କପି କରାଯାଇଥିବା ଇମେଜକୁ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ନିକଟସ୍ଥ ଡିଭାଇସକୁ ପଠାନ୍ତୁ"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ପ୍ରାଥମିକତା ମୋଡ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantର ଅତିଥି ମୋଡ ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 20b5bf21ded3..faa206224214 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"ਸਿਸਟਮ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"ਬੈਟਰੀ ਛੇਤੀ ਹੀ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ਬਾਕੀ"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ਰਾਹੀਂ ਚਾਰਜ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ਆਪਣੇ ਡੀਵਾਈਸ ਨਾਲ ਮਿਲੇ ਚਾਰਜਰ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਿਰਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ਪਿੰਨ ਵਰਤੋ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ਪੈਟਰਨ ਵਰਤੋ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ਬੰਦ ਕਰੋ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ਪੂਰਾ ਸ਼ਾਂਤ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ਸਿਰਫ਼ ਅਲਾਰਮ"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ।"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ਬਲੂਟੁੱਥ।"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ਚਾਲੂ।"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ਅਲਾਰਮ <xliff:g id="TIME">%s</xliff:g> ਲਈ ਸੈੱਟ ਕੀਤਾ ਗਿਆ।"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ਡੈਜ਼ਰਟ ਕੇਸ"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ਕੋਈ ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ਸਥਿਤੀ:&lt;/b&gt; ਦਰਜਾ ਘਟਾਇਆ ਗਿਆ"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ, \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵੀ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵਿਘਨ ਵੀ ਪਾ ਸਕਦੀਆਂ ਹਨ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ਸੰਗੀਤ"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ਵੌਲਿਊਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="battery" msgid="769686279459897127">"ਬੈਟਰੀ"</string>
<string name="headset" msgid="4485892374984466437">"ਹੈੱਡਸੈੱਟ"</string>
@@ -684,6 +697,10 @@
<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">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ਕੀ ਮੋਬਾਈਲ ਡਾਟਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ਕਾਰਜ-ਸਥਾਨ)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ਫ਼ੋਨ ਕਾਲ"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ਰਾਹੀਂ)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ਕੈਮਰਾ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ਟਿਕਾਣਾ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ਡਿਸਕਨੈਕਟ ਹੈ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
<string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ਹਾਲੀਆ ਸੁਨੇਹੇ, ਮਿਸ ਕਾਲਾਂ ਅਤੇ ਸਥਿਤੀ ਸੰਬੰਧੀ ਅੱਪਡੇਟ ਦੇਖੋ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"ਗੱਲਬਾਤ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਸ਼ੇਸ਼ਤਾ ਨੇ ਰੋਕ ਦਿੱਤਾ"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸੁਨੇਹਾ ਭੇਜਿਆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਇੱਕ ਚਿੱਤਰ ਭੇਜਿਆ ਹੈ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸਥਿਤੀ ਅੱਪਡੇਟ ਕੀਤੀ ਹੈ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ਕਿਰਿਆਸ਼ੀਲ ਐਪ</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ਨਵੀਂ ਜਾਣਕਾਰੀ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ਬੰਦ ਕਰੋ"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ਬੰਦ ਹੈ"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤੋਂ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ਕਾਪੀ ਕੀਤੇ UI ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ਕਾਪੀ ਕੀਤੀ ਲਿਖਤ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ਕਾਪੀ ਕੀਤੇ ਗਏ ਚਿੱਤਰ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ \'ਤੇ ਭੇਜੋ"</string>
+ <string name="add" msgid="81036585205287996">"ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <string name="manage_users" msgid="1823875311934643849">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ਇਹ ਸੂਚਨਾ ਸਪਲਿਟ ਸਕ੍ਰੀਨ \'ਤੇ ਘਸੀਟਣ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ।"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ਤਰਜੀਹੀ ਮੋਡ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ਮਹਿਮਾਨ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4572922d60a5..5d61dfe567d2 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI systemu"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Bateria może się wkrótce wyczerpać"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nie można naładować przez USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Użyj ładowarki dostarczonej z urządzeniem"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Twarz rozpoznana"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potwierdzono"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Aby zakończyć, kliknij Potwierdź"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Użyj kodu PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Użyj wzoru"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zamknij"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"całkowita cisza"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tylko alarmy"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nie przeszkadzać."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth włączony."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Półka ze słodkościami"</string>
<string name="start_dreams" msgid="9131802557946276718">"Wygaszacz ekranu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nie przeszkadzać"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Brak dostępnych sparowanych urządzeń"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Powiadomienia"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Usuń wszystkie ciche powiadomienia"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stan:&lt;/b&gt; obniżono ważność"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, przerywa działanie trybu Nie przeszkadzać"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzyka"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendarz"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nie przeszkadzać"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Wł./wył. przyciskami głośności"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Zestaw słuchawkowy"</string>
@@ -694,6 +707,10 @@
<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 jest wyłączone"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth jest wyłączony"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Tryb Nie przeszkadzać jest wyłączony"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tryb Nie przeszkadzać został włączony przez aplikację (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną lub aplikację."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacje działające w tle"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i użycia danych"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Wyłączyć mobilną transmisję danych?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(praca)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Rozmowa telefoniczna"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(przez: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"aparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokalizacja"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odłączono)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nie można przełączyć. Spróbuj ponownie."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
<string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Zobacz ostatnie wiadomości, nieodebrane połączenia i stany"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Rozmowa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Wstrzymane przez tryb Nie przeszkadzać"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> wysyła wiadomość: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> wysyła zdjęcie"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ma nowy stan: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktywnej aplikacji</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktywna aplikacja</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nowa informacja"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktywne aplikacje"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zatrzymaj"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zatrzymano"</string>
@@ -900,14 +921,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Skopiowano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Od: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zamknij UI kopiowania"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edytuj skopiowany tekst"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edytuj skopiowany obraz"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Wyślij na urządzenie w pobliżu"</string>
+ <string name="add" msgid="81036585205287996">"Dodaj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Zarządzaj użytkownikami"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"To powiadomienie nie obsługuje dzielenia ekranu przez przeciąganie."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Sieć Wi‑Fi niedostępna"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tryb priorytetowy"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Tryb gościa w Asystencie włączony"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 1c902b0b8d65..d9bb15b66a11 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Interface do sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"A bateria pode acabar em breve"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Usar o carregador que acompanha o dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"somente alarmes"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não perturbe."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ativado."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
<string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; classificada com menor prioridade"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio. Interrompe o Não perturbe"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompe o Não perturbe"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Fone de ouvido"</string>
@@ -684,6 +697,10 @@
<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">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps sendo executados em segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(por <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ativo</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativos</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+ <string name="add" msgid="81036585205287996">"Adicionar"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo visitante do Google Assistente ativado"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1562abc674ec..73ef834df64d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"IU do sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Pode ficar sem bateria em breve"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restante"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar através de USB."</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utilize o carregador fornecido com o dispositivo."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em Confirmar para concluir."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilizar padrão"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"apenas alarmes"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não incomodar."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ligado."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrina de sobremesas"</string>
<string name="start_dreams" msgid="9131802557946276718">"Proteção de ecrã"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não incomodar"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Sem dispositivos sincronizados disponíveis"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Limpar todas as notificações silenciosas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; passou para classificação inferior"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, interrompe o modo Não incomodar"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão, interrompe o modo Não incomodar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendário"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não incomodar"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho dos botões de volume"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Ausc. com microfone integrado"</string>
@@ -684,6 +697,10 @@
<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 desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Não incomodar desativado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O modo Não incomodar foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O modo Não incomodar foi ativado por uma app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O modo Não incomodar foi ativado por uma regra automática ou por uma app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps em execução em segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Pretende desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(através de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas não atendidas e atualizações de estado"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Colocado em pausa pelo modo Não incomodar"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> tem uma atualização de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app ativa</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativas</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Novas informações"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parada"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Da app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar cópia de IU"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+ <string name="add" msgid="81036585205287996">"Adicionar"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gerir utilizadores"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não pode ser arrastada para o ecrã dividido."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponível"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo Prioridade"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo convidado do Assistente ativado"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação(ões)}other{# notificações}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 1c902b0b8d65..d9bb15b66a11 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Interface do sistema"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"A bateria pode acabar em breve"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Usar o carregador que acompanha o dispositivo"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"somente alarmes"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não perturbe."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ativado."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
<string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; classificada com menor prioridade"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio. Interrompe o Não perturbe"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompe o Não perturbe"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Fone de ouvido"</string>
@@ -684,6 +697,10 @@
<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">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps sendo executados em segundo plano"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(por <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ativo</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativos</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+ <string name="add" msgid="81036585205287996">"Adicionar"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo visitante do Google Assistente ativado"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d520d509edf6..ff409d33fc94 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI sistem"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Este posibil ca bateria să se descarce în curând"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Procent rămas din baterie: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nu se poate realiza încărcarea prin USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Folosiți încărcătorul livrat împreună cu dispozitivul"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Chip autentificat"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Atingeți Confirmați pentru a finaliza"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Folosiți PIN-ul"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Folosiți modelul"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Închideți"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"niciun sunet"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"numai alarme"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nu deranja."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Conexiunea prin Bluetooth este activată."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmă setată pentru <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrina cu dulciuri"</string>
<string name="start_dreams" msgid="9131802557946276718">"Economizor de ecran"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nu deranja"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Niciun dispozitiv conectat disponibil"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificări"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ștergeți toate notificările silențioase"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificări întrerupte prin „Nu deranja”"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Începeți acum"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stare:&lt;/b&gt; clasificată mai jos"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, întrerupe funcția Nu deranja"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon, întrerupe funcția Nu deranja"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritate"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzică"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nu deranja"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Comandă rapidă din butoanele de volum"</string>
<string name="battery" msgid="769686279459897127">"Baterie"</string>
<string name="headset" msgid="4485892374984466437">"Set căști-microfon"</string>
@@ -689,6 +702,10 @@
<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">"Conexiunea Wi-Fi este dezactivată"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Funcția Bluetooth este dezactivată"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Funcția Nu deranja este dezactivată"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Funcția Nu deranja a fost activată de o regulă automată (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Funcția Nu deranja a fost activată de o aplicație (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Funcția Nu deranja a fost activată de o regulă automată sau de o aplicație."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicațiile rulează în fundal"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Dezactivați datele mobile?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(serviciu)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Apel telefonic"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prin <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cameră foto"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"locație"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfon"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deconectat)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nu se poate comuta. Atingeți pentru a încerca din nou."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschideți aplicația."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Deschideți conversația"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Vedeți mesaje recente, apeluri pierdute și actualizări de stare"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversație"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Întrerupt de Nu deranja"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a trimis un mesaj: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a trimis o imagine"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> are o nouă stare: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> de aplicații active</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicație activă</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informații noi"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicații active"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Opriți"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Oprită"</string>
@@ -896,8 +917,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Editați textul copiat"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editați imaginea copiată"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Trimiteți către un dispozitiv din apropiere"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"Adăugați"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Gestionați utilizatorii"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Notificarea nu acceptă tragerea pe ecranul împărțit."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponibil"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modul Prioritate"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modul pentru invitați al Asistentului este activat"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 310a87e1a6da..a79c247b882c 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Интерфейс системы"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батарея скоро разрядится"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Осталось: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Невозможно выполнить зарядку через USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Используйте зарядное устройство из комплекта."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицо распознано"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Подтверждено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Нажмите \"Подтвердить\""</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Использовать графический ключ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыть"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"полная тишина"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"только будильник"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не беспокоить."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Модуль Bluetooth включен."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Будильник установлен на <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Коробка со сладостями"</string>
<string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не беспокоить"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Нет доступных сопряженных устройств"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Уведомления"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговоры"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Отклонить все беззвучные уведомления"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Устройством управляет один из родителей."</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; уровень важности понижен"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Появляется в верхней части уведомлений о сообщениях, а также в качестве фото профиля на заблокированном экране"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране."</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Появляется в верхней части уведомлений о сообщениях, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эти уведомления нельзя изменить."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не беспокоить"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки регулировки громкости"</string>
<string name="battery" msgid="769686279459897127">"Батарея"</string>
<string name="headset" msgid="4485892374984466437">"Гарнитура"</string>
@@ -694,6 +707,10 @@
<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 отключен"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режим \"Не беспокоить\" был включен приложением (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режим \"Не беспокоить\" был включен специальным правилом или приложением."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Приложения, работающие в фоновом режиме"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Отключить мобильный Интернет?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(работа)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонный звонок"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(через приложение \"<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>\")"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"местоположение"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
<string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Будьте в курсе последних сообщений, пропущенных вызовов и обновлений статуса."</string>
<string name="people_tile_title" msgid="6589377493334871272">"Чат"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Приостановлено в режиме \"Не беспокоить\""</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> обновил статус: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> активных приложений</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> активного приложения</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая информация"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активные приложения"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Остановить"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Остановлено"</string>
@@ -900,14 +921,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопировано."</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Из приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыть меню копирования"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменить скопированный текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменить скопированное изображение"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Отправить на устройство поблизости"</string>
+ <string name="add" msgid="81036585205287996">"Добавить"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Управление пользователями"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Это уведомление нельзя перетаскивать между частями разделенного экрана."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сеть Wi‑Fi недоступна"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим приоритета"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Гостевой режим для Ассистента включен"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index e730bb06b222..ffaa4bfccf92 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"පද්ධති UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"බැටරිය ඉක්මනින් අවසන් විය හැකිය"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ඉතිරිව තිබේ"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB හරහා ආරෝපණය කළ නොහැකිය"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ඔබේ උපාංගය සමඟ පැමිණි ආරෝපකය භාවිත කරන්න"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"මුහුණ සත්‍යාපන කළා"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"තහවුරු කළා"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN භාවිත කරන්න"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"රටාව භාවිත කරන්න"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"වසන්න"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"සම්පූර්ණ නිහඬතාව"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"එලාම පමණි"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"බාධා නොකරන්න."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"බ්ලූටූත්."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"බ්ලූටූත් ක්‍රියාත්මකයි."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> සඳහා සීනුව සකස් කර ඇත."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"අතුරුපස අවස්තාව"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"යුගල කළ උපාංග නොතිබේ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"දැනුම් දීම්"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"සංවාද"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"සියලු නිහඬ දැනුම්දීම් හිස් කරන්න"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"මෙම උපාංගය ඔබගේ මාපියන්ගෙන් අයකු විසින් කළමනාකරණය කෙරේ"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;තත්ත්වය:&lt;/b&gt; පහළට ශ්‍රේණිගත කරන ලදි"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ප්‍රමුඛතාව"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> සංවාද විශේෂාංගවලට සහාය නොදක්වයි"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"සංගීතය"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"දින දර්ශනය"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"බාධා නොකරන්න"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"හඩ පරිමා බොත්තම් කෙටිමග"</string>
<string name="battery" msgid="769686279459897127">"බැටරිය"</string>
<string name="headset" msgid="4485892374984466437">"හෙඩ්සෙට්"</string>
@@ -684,6 +697,10 @@
<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 ක්‍රියා විරහිතයි"</string>
<string name="bt_is_off" msgid="7436344904889461591">"බ්ලූටූත් ක්‍රියා විරහිතයි"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"බාධා නොකරන්න ක්‍රියා විරහිතයි"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ස්වයංක්‍රිය රීතියක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ස්වයංක්‍රිය රීතියක් හෝ යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ජංගම දත්ත ක්‍රියාවිරහිත කරන්නද?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"කාර්යාලය"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"දුරකථන ඇමතුම"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> හරහා)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"කැමරාව"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ස්ථානය"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"මයික්‍රෝෆෝනය"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(විසන්ධි විය)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"මාරු කිරීමට නොහැකිය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
<string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"මෑත පණිවිඩ, මඟ හැරුණු ඇමතුම් සහ තත්ත්ව යාවත්කාලීන කිරීම් බලන්න"</string>
<string name="people_tile_title" msgid="6589377493334871272">"සංවාදය"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"බාධා නොකිරීම මගින් විරාම කර ඇත"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> පණිවිඩයක් එවා ඇත: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> රූපයක් යවන ලදී"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> හට තත්ත්ව යාවත්කාලීනයක් ඇත: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one">සක්‍රිය යෙදුම් <xliff:g id="COUNT_1">%s</xliff:g></item>
<item quantity="other">සක්‍රිය යෙදුම් <xliff:g id="COUNT_1">%s</xliff:g></item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"නව තොරතුරු"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"සක්‍රිය යෙදුම්"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"නවත්වන්න"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"නවත්වන ලදි"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"පිටපත් කරන ලදි"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> සිට"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"පිටපත් කළ පෙළ සංස්කරණය කරන්න"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"පිටපත් කළ රූපය සංස්කරණය කරන්න"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"අවට උපාංගය වෙත යවන්න"</string>
+ <string name="add" msgid="81036585205287996">"එක් කරන්න"</string>
+ <string name="manage_users" msgid="1823875311934643849">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"මෙම දැනුම්දීම බෙදුම් තිරය වෙත ඇද ගෙන යාමට සහාය නොදක්වයි."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ලබා ගත නොහැකිය"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ප්‍රමුඛතා ප්‍රකාරය"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"සහායක ආගන්තුක ප්‍රකාරය සබලයි"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a3bbe44a3272..2c2a7c881ff6 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI systému"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batéria sa môže čoskoro minúť"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nedá sa nabíjať cez USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Použite nabíjačku dodanú so zariadením"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Tvár bola overená"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrdené"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Overenie dokončíte klepnutím na Potvrdiť"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použiť PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použiť vzor"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zavrieť"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"úplné ticho"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"iba budíky"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Režim bez vyrušení."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Rozhranie Bluetooth je zapnuté."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Budík nastavený na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Pult s dezertami"</string>
<string name="start_dreams" msgid="9131802557946276718">"Šetrič obrazovky"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režim bez vyrušení"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nie sú k dispozícii žiadne spárované zariadenia"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stav:&lt;/b&gt; Preradené nižšie"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Zobrazuje sa v hornej časti upozornení konverzácie a ako profilová fotka na uzamknutej obrazovke"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Zobrazuje sa v hornej časti upozornení konverzácie a ako profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendár"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režim bez vyrušení"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Skratka tlačidiel hlasitosti"</string>
<string name="battery" msgid="769686279459897127">"Batéria"</string>
<string name="headset" msgid="4485892374984466437">"Náhlavná súprava"</string>
@@ -694,6 +707,10 @@
<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">"Pripojenie Wi‑Fi je vypnuté"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Rozhranie Bluetooth je vypnuté"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Režim bez vyrušení je vypnutý"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim bez vyrušení bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim bez vyrušení bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim bez vyrušení bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikácie sú spustené na pozadí"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Chcete vypnúť mobilné dáta?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(práca)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonický hovor"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prostredníctvom aplikácie <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofón"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojené)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nedá sa prepnúť. Zopakujte klepnutím."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Pozrite si nedávne správy, zmeškané hovory a aktualizácie stavu"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Konverzácia"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastavené režimom bez vyrušení"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) správu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) obrázok"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizáciu statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktívnych aplikácií</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktívna aplikácia</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informácie"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktívne aplikácie"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ukončiť"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastavená"</string>
@@ -903,8 +924,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Upraviť skopírovaný text"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upraviť skopírovaný obrázok"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odoslať do zariadenia v okolí"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Pridať"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Spravovať používateľov"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režim priority"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Režim Asistenta pre hostí je aktivovaný"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d657277431ca..6996d56f2861 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistemski uporabniški vmesnik"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Baterija bo morda kmalu izpraznjena"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Še <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Ni mogoče polniti prek USB-ja"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Uporabite polnilnik, ki je bil priložen napravi"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Pristnost obraza je potrjena"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potrjeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Za dokončanje se dotaknite »Potrdite«"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Uporabi kodo PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Uporabi vzorec"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zapri"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"popolna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne moti."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je vklopljen."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je nastavljen čez: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Vitrina za sladice"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ohranjeval. zaslona"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne moti"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Na voljo ni nobene seznanjene naprave"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obvestila"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Pogovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Brisanje vseh tihih obvestil"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stanje:&lt;/b&gt; Uvrščeno nižje"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu."</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prednostno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij."</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sporočila SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glasba"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Koledar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne moti"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Bližnjica z gumboma za glasnost"</string>
<string name="battery" msgid="769686279459897127">"Baterija"</string>
<string name="headset" msgid="4485892374984466437">"Slušalke z mikrofonom"</string>
@@ -694,6 +707,10 @@
<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 je izklopljen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je izklopljen"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Način »ne moti« je izklopljen"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Samodejno pravilo (<xliff:g id="ID_1">%s</xliff:g>) je vklopilo način »ne moti«."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je vklopila način »ne moti«."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način »ne moti« je bil vklopljen zaradi samodejnega pravila ali aplikacije."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije, ki se izvajajo v ozadju"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Dotaknite se za prikaz podrobnosti porabe baterije in prenosa podatkov"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite izklopiti prenos podatkov v mobilnih omrežjih?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(za delo)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski klic"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prek aplikacije <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokacijo"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(povezava je prekinjena)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Preklop ni mogoč. Če želite poskusiti znova, se dotaknite."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
<string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Več kot <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Ogled nedavnih sporočil, neodgovorjenih klicev in posodobitev stanj"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Pogovor"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"To je začasno zaustavil način »ne moti«."</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sporočilo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>."</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sliko."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je posodobila stanje: <xliff:g id="STATUS">%2$s</xliff:g>."</string>
@@ -891,8 +913,7 @@
<item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacij</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ustavljeno"</string>
@@ -903,8 +924,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirano besedilo"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopirano sliko"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošlji v napravo v bližini"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"Dodaj"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Upravljanje uporabnikov"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"To obvestilo ne podpira vlečenja v razdeljen zaslon."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ni na voljo."</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prednostni način"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Način za goste je omogočen za Pomočnika."</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f8ba65af9300..bea8d835c39b 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Ndërfaqja e përdoruesit të sistemit"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Bateria mund të mbarojë së shpejti"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Ka mbetur edhe <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nuk mund të ngarkohet përmes USB-së"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Përdor karikuesin që ke marrë me pajisjen"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Fytyra u vërtetua"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Konfirmuar"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trokit \"Konfirmo\" për ta përfunduar"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Përdor kodin PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Përdor motivin"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Mbylle"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"heshtje e plotë"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"vetëm alarmet"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Mos shqetëso."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth-i."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"\"Bluetooth-i\" është i aktivizuar."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmi u caktua për në <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"\"Kutia e ëmbëlsirës\""</string>
<string name="start_dreams" msgid="9131802557946276718">"Mbrojtësi i ekranit"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mos shqetëso"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nuk ofrohet për përdorim asnjë pajisje e çiftuar"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Njoftimet"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Pastro të gjitha njoftimet në heshtje"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Statusi:&lt;/b&gt; Renditur më poshtë"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shfaqet në krye të njoftimeve të bisedës, shfaqet si fotografia e profilit në ekranin e kyçjes dhe shfaqet si flluskë"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shfaqet në krye të njoftimeve të bisedës, shfaqet si fotografia e profilit në ekranin e kyçjes dhe ndërpret modalitetin \"Mos shqetëso\""</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes, shfaqet si flluskë dhe ndërpret modalitetin \"Mos shqetëso\""</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Me përparësi"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzikë"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendari"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mos shqetëso"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Shkurtorja e butonave të volumit"</string>
<string name="battery" msgid="769686279459897127">"Bateria"</string>
<string name="headset" msgid="4485892374984466437">"Kufjet me mikrofon"</string>
@@ -684,6 +697,10 @@
<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 është joaktiv"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-i është joaktiv"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Modaliteti \"Mos shqetëso\" është joaktiv"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një aplikacion (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik ose një aplikacion."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacionet që ekzekutohen në sfond"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Të çaktivizohen të dhënat celulare?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(puna)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(nëpërmjet <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamerën"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vendndodhjen"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonin"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(shkëputur)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nuk mund të ndërrohet. Trokit për të provuar përsëri."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
<string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Mbi <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Shiko mesazhet e fundit, telefonatat e humbura dhe përditësimet e statusit"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Biseda"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Vendosur në pauzë nga \"Mos shqetëso\""</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një mesazh: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një imazh"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ka një përditësim të statusit: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacione aktive</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikacion aktiv</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informacion i ri"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikacionet aktive"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ndalo"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ndaluar"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"U kopjua"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Nga <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hiq kopjen e ndërfaqes së përdoruesit"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifiko tekstin e kopjuar"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifiko imazhin e kopjuar"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Dërgo te pajisja në afërsi"</string>
+ <string name="add" msgid="81036585205287996">"Shto"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Menaxho përdoruesit"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ky njoftim nuk mbështet zvarritjen në \"Ekranin e ndarë\"."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nuk ofrohet"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modaliteti \"Me përparësi\""</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modaliteti \"vizitor\" i \"Asistentit\" është aktivizuar"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5d89cf1d3e6c..f373eea9d8e3 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI система"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Батерија ће се можда ускоро испразнити"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Још <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Пуњење преко USB-а није успело"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Користите пуњач који сте добили уз уређај"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"потпуна тишина"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не узнемиравај."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth је укључен."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм је подешен за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Витрина са посластицама"</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">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Није доступан ниједан упарени уређај"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
@@ -494,6 +504,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; Рангирано ниже"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, прекида режим Не узнемиравај"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
@@ -571,6 +583,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не узнемиравај"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Пречица за дугмад за јачину звука"</string>
<string name="battery" msgid="769686279459897127">"Батерија"</string>
<string name="headset" msgid="4485892374984466437">"Наглавне слушалице"</string>
@@ -689,6 +702,10 @@
<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">"WiFi је искључен"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Апликације покренуте у позадини"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Додирните за детаље о батерији и потрошњи података"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Желите да искључите мобилне податке?"</string>
@@ -713,6 +730,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(посао)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски позив"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преко: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -812,6 +831,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
@@ -845,6 +866,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано режимом Не узнемиравај"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> је послао/ла поруку: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање статуса: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
<item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> активне апликације</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> активних апликација</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Заустави"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Заустављено"</string>
@@ -893,14 +914,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано је"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Из: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Одбаци копирање корисничког интерфејса"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Измените копирани текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Измените копирану слику"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Пошаљи на уређај у близини"</string>
+ <string name="add" msgid="81036585205287996">"Додај"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Омогућен је режим госта у Помоћнику"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index b9a3ab106fcd..638ba9f7e4f2 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Gränssnitt"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batteriet kan ta slut snart"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> kvar"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Det går inte att ladda via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Använd laddaren som följde med enheten."</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet har autentiserats"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekräftat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Stäng"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"helt tyst"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"endast alarm"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Stör ej."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth på."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmet ringer <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessertdisken"</string>
<string name="start_dreams" msgid="9131802557946276718">"Skärmsläckare"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Stör ej"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Det finns inga kopplade enheter tillgängliga"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Aviseringar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Sänkt"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, åsidosätter Stör ej"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla, åsidosätter Stör ej"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Stör ej"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Genväg till volymknappar"</string>
<string name="battery" msgid="769686279459897127">"Batteri"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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">"wifi är inaktiverat"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth är inaktiverat"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Stör ej är inaktiverat"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Stör ej aktiverades via en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Stör ej aktiverades via en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Stör ej aktiverades via en automatisk regel eller en app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Appar körs i bakgrunden"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tryck för information om batteri- och dataanvändning"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vill du inaktivera mobildata?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(jobb)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtal"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"plats"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frånkopplad)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Misslyckat byte. Tryck och försök igen."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
<string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"över <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Se de senaste meddelandena, missade samtal och statusuppdateringar"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Konversation"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Pausad av Stör ej"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> skickade ett meddelande: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> skickade en bild"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har gjort en statusuppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiva appar</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiva appar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppa"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppad"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopierades"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Från <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Stäng användargränssnittet för kopiering"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Redigera kopierad text"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redigera kopierad bild"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Skicka till enhet i närheten"</string>
+ <string name="add" msgid="81036585205287996">"Lägg till"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Hantera användare"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Det går inte att dra den här aviseringen till delad skärm."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi är inte tillgängligt"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetsläge"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gästläget för assistenten är aktiverat"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 803a2b56067c..931f6343b7df 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Kiolesura"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Chaji inaweza kuisha hivi karibuni"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Imebakisha <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Haiwezi kuchaji kupitia USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Tumia chaja ambayo ilikuja na kifaa chako"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Uso umethibitishwa"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Imethibitishwa"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Gusa Thibitisha ili ukamilishe"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Tumia PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Tumia mchoro"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Funga"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"kimya kabisa"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"kengele pekee"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Usinisumbue."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth imewashwa."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Kengele imewashwa na italia <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Sanduku la Vitindamlo"</string>
<string name="start_dreams" msgid="9131802557946276718">"Taswira ya skrini"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Usinisumbue"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Hakuna vifaa vilivyooanishwa vinavyopatikana"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Arifa"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Hali:&lt;/b&gt; Imeorodheshwa Katika Nafasi ya Chini"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Hukatiza kipengele cha Usinisumbue"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo na hukatiza kipengele cha Usinisumbue"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Kipaumbele"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziki"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Usinisumbue"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Njia ya mkato ya vitufe vya sauti"</string>
<string name="battery" msgid="769686279459897127">"Betri"</string>
<string name="headset" msgid="4485892374984466437">"Vifaa vya sauti"</string>
@@ -684,6 +697,10 @@
<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 imezimwa"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth imezimwa"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Kipengele cha Usinisumbue kimezimwa"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki <xliff:g id="ID_1">%s</xliff:g>."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Kipengele cha usinisumbue kimewashwa na programu (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki au programu."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Programu zinatumika chinichini"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Gusa ili upate maelezo kuhusu betri na matumizi ya data"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Ungependa kuzima data ya mtandao wa simu?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kazini)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Simu"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kupitia <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"mahali"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"maikrofoni"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(imetenganishwa)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Imeshindwa kubadilisha. Gusa ili ujaribu tena."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
<string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Angalia ujumbe wa hivi majuzi, simu ambazo hukujibu na taarifa za hali"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Mazungumzo"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Imesimamishwa na kipengele cha Usinisumbue"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ametuma ujumbe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ametuma picha"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ana taarifa kuhusu hali: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">Programu <xliff:g id="COUNT_1">%s</xliff:g> zinatumika</item>
<item quantity="one">Programu <xliff:g id="COUNT_0">%s</xliff:g> inatumika</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maelezo mapya"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Programu zinazotumika"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Simamisha"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imesimamishwa"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Imenakiliwa"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Kutoka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ondoa kiolesura cha nakala"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Badilisha maandishi yaliyonakiliwa"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Badilisha picha iliyonakiliwa"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Tuma kwenye kifaa kilicho karibu"</string>
+ <string name="add" msgid="81036585205287996">"Weka"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Dhibiti watumiaji"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Arifa hii hairuhusu kuburuta kwenye Skrini iliyogawanyika."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi haipatikani"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Hali ya kipaumbele"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Matumizi ya wageni ya Mratibu yamewashwa"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 4f95811b21b3..72578d78f96b 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -34,17 +34,47 @@
<item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">0.45</item>
<dimen name="controls_task_view_right_margin">8dp</dimen>
- <!-- Distance that the full shade transition takes in order for qs to fully transition to the
- shade -->
- <dimen name="lockscreen_shade_qs_transition_distance">200dp</dimen>
+ <dimen name="split_shade_header_height">42dp</dimen>
- <!-- Distance that the full shade transition takes in order for scrim to fully transition to
- the shade (in alpha) -->
- <dimen name="lockscreen_shade_scrim_transition_distance">200dp</dimen>
+ <!-- Distance that the full shade transition takes in order to complete by tapping on a button
+ like "expand". -->
+ <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
+
+ <!-- Distance that the full shade transition takes in order to complete. -->
+ <dimen name="lockscreen_shade_full_transition_distance">200dp</dimen>
<!-- Distance that the full shade transition takes in order for media to fully transition to
- the shade -->
+ the shade -->
<dimen name="lockscreen_shade_media_transition_distance">200dp</dimen>
- <dimen name="notification_panel_margin_horizontal">12dp</dimen>
+ <!-- Distance that the full shade transition takes in order for scrim to fully transition to
+ the shade (in alpha) -->
+ <dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the keyguard content on
+ NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
+ <dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">80dp</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the notification shell to fully
+ expand. -->
+ <dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the Quick Settings to fully
+ fade and expand. -->
+ <dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
+ change.
+ On split-shade, there should be no depth effect, so setting the value to 0. -->
+ <dimen name="lockscreen_shade_depth_controller_transition_distance">0dp</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+ fade. -->
+ <dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Used for StatusBar to know that a transition is in progress. At the moment it only checks
+ whether the progress is > 0, therefore this value is not very important. -->
+ <dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <dimen name="notification_panel_margin_horizontal">24dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 71c195896051..2b9917a3cb79 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -23,5 +23,5 @@
<dimen name="keyguard_split_shade_top_margin">72dp</dimen>
- <dimen name="notification_panel_margin_horizontal">24dp</dimen>
+ <dimen name="split_shade_header_height">56dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 094559fb7a53..e856294f2ed3 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"சாதனத்தின் UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"பேட்டரி விரைவில் தீர்ந்துவிடக்கூடும்"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> உள்ளது"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB மூலம், சார்ஜ் செய்ய முடியாது"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"உங்கள் சாதனத்துடன் வழங்கப்பட்ட சார்ஜரைப் பயன்படுத்தவும்"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"முகம் அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"பின்னைப் பயன்படுத்து"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"பேட்டர்னைப் பயன்படுத்து"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"மூடு"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"முழு அமைதி"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"அலாரங்கள் மட்டும்"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"தொந்தரவு செய்ய வேண்டாம்."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"புளூடூத்."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"புளூடூத் இயக்கத்தில்."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> மணிக்கு அலாரம் அமைக்கப்பட்டது."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"இனிப்பு வடிவங்கள்"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"இணைக்கப்பட்ட சாதனங்கள் இல்லை"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"அறிவிப்புகள்"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"உரையாடல்கள்"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"சைலன்ட் அறிவிப்புகள் அனைத்தையும் அழிக்கும்"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"அறிவிப்புகள் இல்லை"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;நிலை:&lt;/b&gt; முக்கியத்துவம் குறைக்கப்பட்டது"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும்"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும்"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"முன்னுரிமை"</string>
<string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"மியூசிக்"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"தொந்தரவு செய்ய வேண்டாம்"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ஒலியளவுப் பொத்தான்களுக்கான ஷார்ட்கட்"</string>
<string name="battery" msgid="769686279459897127">"பேட்டரி"</string>
<string name="headset" msgid="4485892374984466437">"ஹெட்செட்"</string>
@@ -684,6 +697,10 @@
<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">"வைஃபை முடக்கத்தில் உள்ளது"</string>
<string name="bt_is_off" msgid="7436344904889461591">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, ஆப்ஸ் (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி அல்லது ஆப்ஸ் இயக்கியுள்ளது."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"பின்னணியில் இயங்கும் ஆப்ஸ்"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"மொபைல் டேட்டாவை ஆஃப் செய்யவா?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(பணி)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"மொபைல் அழைப்பு"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> மூலம்)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"கேமரா"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"இருப்பிடம்"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"மைக்ரோஃபோன்"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
<string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"சமீபத்திய மெசேஜ்களையும் தவறிய அழைப்புகளையும் ஸ்டேட்டஸ் அப்டேட்களையும் பார்க்கலாம்"</string>
<string name="people_tile_title" msgid="6589377493334871272">"உரையாடல்"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"தொந்தரவு செய்ய வேண்டாம் அம்சத்தால் இடைநிறுத்தப்பட்டது"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு மெசேஜ் அனுப்பியுள்ளார்: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு படம் அனுப்பியுள்ளார்"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> புதிய ஸ்டேட்டஸ் வைத்துள்ளார்: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ஆப்ஸ் செயலில் உள்ளன</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ஆப்ஸ் செயலில் உள்ளது</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"புதிய தகவல்கள்"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"செயலிலுள்ள ஆப்ஸ்"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"நிறுத்து"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"இயங்கவில்லை"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"நகலெடுத்த வார்த்தைகளைத் திருத்து"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"நகலெடுத்த படத்தைத் திருத்து"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"அருகிலுள்ள சாதனத்திற்கு அனுப்பு"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"சேர்"</string>
+ <string name="manage_users" msgid="1823875311934643849">"பயனர்களை நிர்வகித்தல்"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"பிரிக்கப்பட்ட திரைக்குள் இந்த அறிவிப்பை இழுத்துவிட முடியாது."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"வைஃபை கிடைக்கவில்லை"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"முன்னுரிமைப் பயன்முறை"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant கெஸ்ட் பயன்முறை இயக்கப்பட்டுள்ளது"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 59e8ef4a6e87..6ef8f5086535 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"సిస్టమ్ UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"బ్యాటరీ త్వరలో ఖాళీ అవ్వచ్చు"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> మిగిలి ఉంది"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ద్వారా ఛార్జ్ చేయలేరు"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"మీ పరికరంతో వచ్చిన ఛార్జర్‌ను ఉపయోగించండి"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ముఖం ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించు"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించు"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"మూసివేస్తుంది"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"మొత్తం నిశ్శబ్దం"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"అలారాలు మాత్రమే"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"అంతరాయం కలిగించవద్దు."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"బ్లూటూత్."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"బ్లూటూత్ ఆన్‌లో ఉంది."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>కి అలారం సెట్ చేయబడింది."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"డెజర్ట్ కేస్"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"జత చేసిన పరికరాలు ఏవీ అందుబాటులో లేవు"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> బ్యాటరీ"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"నోటిఫికేషన్‌లు"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించు"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"నోటిఫికేషన్‌లు లేవు"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;స్టేటస్:&lt;/b&gt; తక్కువ ర్యాంక్‌కు సర్దుబాటు చేయబడింది"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ప్రాధాన్యత"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్‌లను సపోర్ట్ చేయదు"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"మ్యూజిక్"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"అంతరాయం కలిగించవద్దు"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"వాల్యూమ్ బటన్‌ల షార్ట్‌కట్"</string>
<string name="battery" msgid="769686279459897127">"బ్యాటరీ"</string>
<string name="headset" msgid="4485892374984466437">"హెడ్‌సెట్"</string>
@@ -684,6 +697,10 @@
<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 ఆఫ్‌లో ఉంది"</string>
<string name="bt_is_off" msgid="7436344904889461591">"బ్లూటూత్ ఆఫ్‌లో ఉంది"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"అంతరాయం కలిగించవద్దు ఆఫ్‌లో ఉంది"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ఆటోమేటిక్‌ నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"యాప్ (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ఆటోమేటిక్‌ నియమం లేదా యాప్ ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"నేపథ్యంలో అమలు అవుతున్న ఆప్‌లు"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"మొబైల్ డేటాను ఆఫ్ చేయాలా?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ఆఫీస్)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ఫోన్ కాల్"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ద్వారా)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"కెమెరా"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"లొకేషన్"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"మైక్రోఫోన్"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(డిస్కనెక్ట్ అయ్యింది)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"స్విచ్ చేయడం సాధ్యం కాదు. మళ్ళీ ట్రై చేయడానికి ట్యాప్ చేయండి."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
<string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్‌లు, మిస్స్‌డ్‌ కాల్స్‌, అలాగే స్టేటస్ అప్‌డేట్‌లను చూడండి"</string>
<string name="people_tile_title" msgid="6589377493334871272">"సంభాషణ"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"అంతరాయం కలిగించవద్దు ద్వారా పాజ్ చేయబడింది"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> మెసేజ్‌ను పంపారు: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ఇమేజ్‌ను పంపారు"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, స్టేటస్‌ను గురించిన అప్‌డేట్‌ను కలిగి ఉన్నారు: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> యాక్టివ్‌గా ఉన్న యాప్‌లు</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> యాక్టివ్‌గా ఉన్న యాప్</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"కొత్త సమాచారం"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ఆపివేయండి"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ఆపివేయబడింది"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"కాపీ చేసిన టెక్స్ట్‌ను ఎడిట్ చేయండి"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"కాపీ చేసిన ఇమేజ్‌లను ఎడిట్ చేయండి"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"సమీపంలోని పరికరానికి పంపండి"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"జోడించండి"</string>
+ <string name="manage_users" msgid="1823875311934643849">"యూజర్‌లను మేనేజ్ చేయండి"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"ఈ నోటిఫికేషన్ స్ప్లిట్‌స్క్రీన్‌కు లాగడానికి సపోర్ట్ చేయదు."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi అందుబాటులో లేదు"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ముఖ్యమైన ఫైల్స్ మోడ్"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"అసిస్టెంట్ గెస్ట్ మోడ్ ఎనేబుల్ చేయబడింది"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a20744794360..9072db444912 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"อินเทอร์เฟซผู้ใช้ของระบบ"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"แบตเตอรี่อาจหมดเร็วๆ นี้"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"เหลืออีก <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"ชาร์จผ่าน USB ไม่ได้"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ใช้ที่ชาร์จที่ให้มาพร้อมกับอุปกรณ์"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ยืนยันแล้ว"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ใช้ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ใช้รูปแบบ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ปิด"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ปิดเสียงทั้งหมด"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"เฉพาะปลุกเท่านั้น"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ห้ามรบกวน"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"บลูทูธ"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"บลูทูธเปิดอยู่"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ตั้งเวลาปลุกไว้ที่ <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ชั้นแสดงของหวาน"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ไม่มีอุปกรณ์ที่จับคู่ที่สามารถใช้ได้"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"การแจ้งเตือน"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ไม่มีการแจ้งเตือน"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;สถานะ:&lt;/b&gt; อันดับต่ำลง"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก ปรากฏเป็นบับเบิล"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก แสดงในโหมดห้ามรบกวน"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก ปรากฏเป็นบับเบิล แสดงในโหมดห้ามรบกวน"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"สำคัญ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่รองรับฟีเจอร์การสนทนา"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"เพลง"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ปฏิทิน"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ห้ามรบกวน"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ทางลัดปุ่มปรับระดับเสียง"</string>
<string name="battery" msgid="769686279459897127">"แบตเตอรี่"</string>
<string name="headset" msgid="4485892374984466437">"ชุดหูฟัง"</string>
@@ -684,6 +697,10 @@
<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 ปิดอยู่"</string>
<string name="bt_is_off" msgid="7436344904889461591">"บลูทูธปิดอยู่"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\"ห้ามรบกวน\" ปิดอยู่"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติ (<xliff:g id="ID_1">%s</xliff:g>)"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"มีการเปิด \"ห้ามรบกวน\" โดยแอป (<xliff:g id="ID_1">%s</xliff:g>)"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติหรือแอป"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"ปิดอินเทอร์เน็ตมือถือไหม"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ที่ทำงาน)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"การโทร"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ผ่านทาง <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"กล้องถ่ายรูป"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ตำแหน่ง"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ไมโครโฟน"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ยกเลิกการเชื่อมต่อแล้ว)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"เปลี่ยนไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
<string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"ดูข้อความล่าสุด สายที่ไม่ได้รับ และการอัปเดตสถานะ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"การสนทนา"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"หยุดชั่วคราวโดยฟีเจอร์ห้ามรบกวน"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ส่งข้อความ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ส่งรูปภาพ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> มีการอัปเดตสถานะ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other">มี <xliff:g id="COUNT_1">%s</xliff:g> แอปที่ใช้งานอยู่</item>
<item quantity="one">มี <xliff:g id="COUNT_0">%s</xliff:g> แอปที่ใช้งานอยู่</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"คัดลอกแล้ว"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"จาก <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ปิด UI การคัดลอก"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"แก้ไขข้อความที่คัดลอก"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"แก้ไขรูปภาพที่คัดลอก"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ส่งไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="add" msgid="81036585205287996">"เพิ่ม"</string>
+ <string name="manage_users" msgid="1823875311934643849">"จัดการผู้ใช้"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"การแจ้งเตือนนี้ไม่รองรับการลากเพื่อแบ่งหน้าจอ"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ใช้ Wi‑Fi ไม่ได้"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"โหมดลำดับความสำคัญ"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"เปิดใช้โหมดผู้มาเยือนของ Assistant แล้ว"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index db9c788037f9..b518c603458d 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"UI ng System"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Malapit nang maubos ang baterya"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> na lang ang natitira"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Hindi makapag-charge sa pamamagitan ng USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Gamitin ang charger na kasama ng iyong device"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Na-authenticate ang mukha"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Nakumpirma"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"I-tap ang Kumpirmahin para kumpletuhin"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gumamit ng PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gumamit ng pattern"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Isara"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ganap na katahimikan"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"mga alarm lang"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Huwag Istorbohin."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Naka-on ang Bluetooth."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Nakatakda ang alarm nang <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Huwag Istorbohin"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Walang available na mga magkapares na device"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Mga Notification"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"I-clear ang lahat ng silent na notification"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Mga notification na na-pause ng Huwag Istorbohin"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Na-rank nang Mas Mababa"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, naaabala ang Huwag Istorbohin"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble, naaabala ang Huwag Istorbohin"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendaryo"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Huwag Istorbohin"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Shortcut ng mga button ng volume"</string>
<string name="battery" msgid="769686279459897127">"Baterya"</string>
<string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
<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">"Naka-off ang Wi-Fi"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Naka-off ang Bluetooth"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Naka-off ang Huwag Istorbohin"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Na-on ang Huwag Istorbohin dahil sa isang app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan o app."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Tumatakbo ang mga app sa background"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"I-off ang mobile data?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabaho)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tawag sa telepono"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(sa pamamagitan ng <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasyon"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikropono"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nadiskonekta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Hindi makalipat. I-tap para subukan ulit."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
<string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Tingnan ang mga kamakailang mensahe, hindi nasagot na tawag, at update sa status"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Pag-uusap"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Na-pause ng Huwag Istorbohin"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng mensahe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng larawan"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"May update sa status si <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktibong app</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> na aktibong app</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Bagong impormasyon"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Mga aktibong app"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ihinto"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Inihinto"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nakopya"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Mula sa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"I-dismiss ang UI ng pagkopya"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"I-edit ang kinopyang text"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"I-edit ang kinopyang larawan"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ipadala sa kalapit na device"</string>
+ <string name="add" msgid="81036585205287996">"Magdagdag"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Pamahalaan ang mga user"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Hindi sinusuportahan ng notification na ito ang pag-drag sa Splitscreen."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Hindi available ang Wi‑Fi"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Naka-enable ang guest mode ng Assistant"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 308af4f3cb3a..0f56057ef082 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Sistem Arayüzü"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Pil kısa süre sonra bitebilir"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> kaldı"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ile şarj edilemiyor"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Cihazınızla birlikte gelen şarj cihazını kullanın"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yüz kimliği doğrulandı"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Onaylandı"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamak için Onayla\'ya dokunun"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kullan"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Deseni kullan"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Kapat"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"tamamen sessiz"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"yalnızca alarmlar"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Rahatsız Etmeyin."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth açık."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm saati: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Tatlı Kutusu"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekran koruyucu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Rahatsız Etmeyin"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Kullanılabilir eşlenmiş cihaz yok"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirimler"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sessiz bildirimlerin tümünü temizle"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Durum:&lt;/b&gt; Daha Düşük Sıralandı"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Öncelikli"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Müzik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Takvim"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Rahatsız Etmeyin"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Ses düğmeleri kısayolu"</string>
<string name="battery" msgid="769686279459897127">"Pil"</string>
<string name="headset" msgid="4485892374984466437">"Mikrofonlu kulaklık"</string>
@@ -684,6 +697,10 @@
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>, <xliff:g id="CARRIER_NAME">%1$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="5389597396308001471">"Kablosuz bağlantı kapalı"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth kapalı"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Rahatsız Etmeyin kapalı"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Rahatsız Etmeyin ayarı bir otomatik kural (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rahatsız Etmeyin ayarı bir uygulama (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Rahatsız Etmeyin ayarı bir otomatik kural veya uygulama tarafından açıldı."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Arka planda çalışan uygulamalar"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil veri kapatılsın mı?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(iş)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Sesli arama"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> aracılığıyla)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"konum"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kesildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Geçiş yapılamıyor. Tekrar denemek için dokunun."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
<string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Yeni mesajları, cevapsız aramaları ve durum güncellemelerini görün"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Görüşme"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> bir mesaj gönderdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> bir resim gönderdi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, durumunu güncelledi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> etkin uygulama</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> etkin uygulama</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni bilgi"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Etkin uygulamalar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Durdur"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Durduruldu"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasından"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopyalanan kullanıcı arayüzünü kapat"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanan metni düzenle"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanan resmi düzenle"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yakındaki cihaza gönder"</string>
+ <string name="add" msgid="81036585205287996">"Ekle"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Kullanıcıları yönet"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirim, bölünmüş ekrana sürüklenmeyi desteklemiyor."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Kablosuz kullanılamıyor"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Öncelik modu"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Asistan misafir modu etkinleştirildi"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 01610607154e..fa9af2e1c77f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Інтерфейс системи"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Акумулятор може невдовзі розрядитися"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Залишилося <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Не вдається зарядити через USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Використовуйте зарядний пристрій, який входить у комплект пристрою"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Обличчя автентифіковано"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Ввести PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Намалювати ключ"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Закрити"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"без сигналів"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"лише будильники"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не турбувати."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth увімк."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Сигнал установлено на <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Вітрина десертів"</string>
<string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбувати"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Немає спарених пристроїв"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string>
@@ -354,6 +363,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Сповіщення"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Розмови"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Очистити всі беззвучні сповіщення"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Режим \"Не турбувати\" призупинив сповіщення"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
@@ -497,6 +507,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет знижено"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
@@ -576,6 +588,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбувати"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки гучності на корпусі"</string>
<string name="battery" msgid="769686279459897127">"Акумулятор"</string>
<string name="headset" msgid="4485892374984466437">"Гарнітура"</string>
@@ -694,6 +707,10 @@
<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 вимкнено"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth вимкнено"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не турбувати\" вимкнено"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматичне правило ввімкнуло режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Додаток увімкнув режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматичне правило або додаток увімкнули режим \"Не турбувати\"."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Додатки, які працюють у фоновому режимі"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Вимкнути мобільний Інтернет?"</string>
@@ -718,6 +735,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(робота)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонний дзвінок"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(через <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"місце"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"мікрофон"</string>
@@ -818,6 +837,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(від’єднано)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не вдалося змінити підключення. Натисніть, щоб повторити спробу."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
<string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
@@ -851,6 +872,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Переглядайте останні повідомлення, пропущені виклики й оновлення статусу"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Розмова"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Призупинено функцією \"Не турбувати\""</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> надсилає повідомлення: \"<xliff:g id="NOTIFICATION">%2$s</xliff:g>\""</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> надсилає зображення"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> публікує новий статус: \"<xliff:g id="STATUS">%2$s</xliff:g>\""</string>
@@ -891,8 +913,7 @@
<item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> активних додатків</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> активного додатка</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова інформація"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активні додатки"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Зупинити"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Зупинено"</string>
@@ -900,14 +921,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопійовано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"З додатка <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрити вікно копіювання"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редагувати скопійований текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редагувати скопійоване зображення"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Надіслати на пристрій поблизу"</string>
+ <string name="add" msgid="81036585205287996">"Додати"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Керувати користувачами"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Це сповіщення не підтримує режим розділеного екрана."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Мережа Wi-Fi недоступна"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим пріоритету"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Увімкнено режим гостя Асистента"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ce492dd71fb4..35760212155d 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"‏سسٹم UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"بیٹری جلد ہی ختم ہو سکتی ہے"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی ہے"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"‏USB کے ذریعے چارج نہیں کر سکتے"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"اپنے آلہ کے ساتھ ملنے والے چارجر کا استعمال کریں"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چہرے کی تصدیق ہو گئی"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تصدیق شدہ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‏PIN استعمال کریں"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"پیٹرن کا استعمال کریں"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"بند کریں"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"مکمل خاموشی"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"صرف الارمز"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ڈسٹرب نہ کریں۔"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"بلوٹوتھ۔"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"بلوٹوتھ آن ہے۔"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"الارم <xliff:g id="TIME">%s</xliff:g> کیلئے سیٹ ہے۔"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ڈیزرٹ کیس"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"کوئی جوڑا بنائے ہوئے آلات دستیاب نہیں ہیں"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> بیٹری"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اطلاعات"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"گفتگوئیں"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"سبھی خاموش اطلاعات کو صاف کریں"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"یہ آلہ آپ کے والدین کے زیر انتظام ہے"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;اسٹیٹس:&lt;/b&gt; کو کم درجہ دیا گیا"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ترجیح"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ گفتگو کی خصوصیات کو سپورٹ نہیں کرتی ہے"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"کیلنڈر"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ڈسٹرب نہ کریں"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"والیوم بٹنز کے شارٹ کٹ"</string>
<string name="battery" msgid="769686279459897127">"بیٹری"</string>
<string name="headset" msgid="4485892374984466437">"ہیڈ سیٹ"</string>
@@ -684,6 +697,10 @@
<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 آف ہے"</string>
<string name="bt_is_off" msgid="7436344904889461591">"بلوٹوتھ آف ہے"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"\'ڈسٹرب نہ کریں\' آف ہے"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'ڈسٹرب نہ کریں\' کسی ایپ (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول یا ایپ کے ذریعے آن ہو گیا تھا۔"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"ایپس پس منظر میں چل رہی ہیں"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"موبائل ڈیٹا آف کریں؟"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(دفتر)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"فون کال"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> کے ذریعے)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"کیمرا"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"مقام"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"مائیکروفون"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غیر منسلک ہے)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"سوئچ نہیں کر سکتے۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
<string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"حالیہ پیغامات، چھوٹی ہوئی کالز اور اسٹیٹس اپ ڈیٹس دیکھیں"</string>
<string name="people_tile_title" msgid="6589377493334871272">"گفتگو"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"\'ڈسٹرب نہ کریں\' کے ذریعے موقوف کیا گیا"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک پیغام بھیجا: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک تصویر بھیجی"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> نے اسٹیٹس کو اپ ڈیٹ کر دیا ہے: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> فعال ایپس</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> فعال ایپ</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"نئی معلومات"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"فعال ایپس"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"روکیں"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"رکی ہوئی ہے"</string>
@@ -889,8 +910,13 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"کاپی کردہ ٹیکسٹ میں ترمیم کریں"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"کاپی کردہ تصویر میں ترمیم کریں"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"قریبی آلے کو بھیجیں"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="add" msgid="81036585205287996">"شامل کریں"</string>
+ <string name="manage_users" msgid="1823875311934643849">"صارفین کا نظم کریں"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"یہ اطلاع اسپلٹ اسکرین کو گھسیٹنے کو سپورٹ نہیں کرتا ہے۔"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi-Fi دستیاب نہیں ہے"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ترجیحی وضع"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"اسسٹنٹ مہمان وضع فعال ہے"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 6d6c3714fcdc..0cead719b0a4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Tizim interfeysi"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Batareya tez orada tugaydi"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> qoldi"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB orqali quvvatlash imkonsiz"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Qurilmangiz bilan kelgan quvvatlash moslamasidan foydalaning"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yuzingiz aniqlandi"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kod kiritish"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Grafik kalitdan foydalanish"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Yopish"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"jimjitlik"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"faqat signallar"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Bezovta qilinmasin."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth yoqilgan."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signal <xliff:g id="TIME">%s</xliff:g> da chalinadi."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Ekran lavhasi"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bezovta qilinmasin"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ulangan qurilmalar topilmadi"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirishnomalar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilinadi"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Holati:&lt;/b&gt; Quyi darajaga tushirildi"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, bulutcha sifatida chiqadi"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, Bezovta qilinmasin rejimini bekor qiladi"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, bulutcha sifatida chiqadi, Bezovta qilinmasin rejimini bekor qiladi"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqa"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Taqvim"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bezovta qilinmasin"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Ovoz balandligini boshqarish tugmalari"</string>
<string name="battery" msgid="769686279459897127">"Batareya"</string>
<string name="headset" msgid="4485892374984466437">"Audio moslama"</string>
@@ -684,6 +697,10 @@
<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 o‘chiq"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth o‘chiq"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Bezovta qilinmasin rejimi o‘chiq"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Bezovta qilinmasin rejimi avtomatik qoida (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Bezovta qilinmasin rejimi ilova (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Bezovta qilinmasin rejimi ilova yoki avtomatik qoida tomonidan yoqilgan."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Fonda ishlayotgan ilovalar"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil internet uzilsinmi?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ish)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon chaqiruvi"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> orqali)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"joylashuv"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(uzildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Xatolik. Qayta urinish uchun bosing."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
<string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Oxirgi xabarlar, javobsiz chaqiruvlar va holat yangilanishlari"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Suhbat"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Bezovta qilinmasin rejimi pauza qildi"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> xabar yubordi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> rasm yubordi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ahvolini yangiladi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ta faol ilova</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ta faol ilova</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yangi axborot"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Faol ilovalar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Toʻxtatildi"</string>
@@ -886,14 +907,16 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nusxa olindi"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Manba: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI nusxasini bekor qilish"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
- <skip />
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Nusxa olingan matnni tahrirlash"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Nusxa olingan rasmni tahrirlash"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaqin-atrofdagi qurilmaga yuborish"</string>
+ <string name="add" msgid="81036585205287996">"Kiritish"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Foydalanuvchilarni boshqarish"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imtiyozli rejim"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistentli mehmon rejimi yoqildi"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5d69e030b194..a5609eb8a6d7 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Giao diện người dùng hệ thống"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Có thể sắp hết pin"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"Còn lại <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Không thể sạc qua USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Sử dụng bộ sạc đi kèm với thiết bị"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Đã xác thực khuôn mặt"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ðã xác nhận"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Nhấn vào Xác nhận để hoàn tất"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Dùng mã PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Dùng hình mở khóa"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Đóng"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"hoàn toàn tắt tiếng"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"chỉ chuông báo"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Không làm phiền."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bật."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Báo thức được đặt cho <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Tủ trưng bày bánh ngọt"</string>
<string name="start_dreams" msgid="9131802557946276718">"Trình bảo vệ m.hình"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Không làm phiền"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Không có thiết bị nào được ghép nối"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Thông báo"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Xóa tất cả thông báo im lặng"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Trạng thái:&lt;/b&gt; Đã giảm mức độ quan trọng"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, làm gián đoạn chế độ Không làm phiền"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng, làm gián đoạn chế độ Không làm phiền"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Mức độ ưu tiên"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Âm nhạc"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Lịch"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Không làm phiền"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Phím tắt các nút âm lượng"</string>
<string name="battery" msgid="769686279459897127">"Pin"</string>
<string name="headset" msgid="4485892374984466437">"Tai nghe"</string>
@@ -684,6 +697,10 @@
<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 tắt"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Không làm phiền đã được một ứng dụng (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Không làm phiền đã được một quy tắc tự động hoặc ứng dụng bật."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Ứng dụng đang chạy trong nền"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Tắt dữ liệu di động?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(công việc)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Cuộc gọi điện thoại"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(thông qua <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"máy ảnh"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vị trí"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrô"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(đã ngắt kết nối)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Không thể chuyển đổi. Hãy nhấn để thử lại."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
<string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Hơn <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Xem các tin nhắn, cuộc gọi nhỡ và thông tin cập nhật trạng thái gần đây"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Cuộc trò chuyện"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Đã tạm dừng do chế độ Không làm phiền"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một tin nhắn: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một hình ảnh"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> đã cập nhật trạng thái: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ứng dụng đang hoạt động</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ứng dụng đang hoạt động</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Thông tin mới"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ứng dụng đang hoạt động"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dừng"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Đã dừng"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Đã sao chép"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Từ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Đóng giao diện người dùng sao chép"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Chỉnh sửa văn bản đã sao chép"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Chỉnh sửa hình ảnh đã sao chép"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Gửi đến thiết bị ở gần"</string>
+ <string name="add" msgid="81036585205287996">"Thêm"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Quản lý người dùng"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Thông báo này không hỗ trợ thao tác kéo để Chia đôi màn hình."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Không có Wi‑Fi"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Chế độ ưu tiên"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Đã bật chế độ khách cho Trợ lý"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f03290709a48..0610b5917f46 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"系统界面"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"电池电量可能很快就要耗尽"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"无法通过 USB 充电"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"使用设备随附的充电器"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔身份验证成功"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已确认"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"点按“确认”即可完成"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 码"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用图案"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"关闭"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全静音"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"仅限闹钟"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"勿扰。"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"蓝牙。"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"蓝牙开启。"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"闹钟已设置为:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"甜品盒"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"没有可用的配对设备"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有无声通知"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;状态&lt;/b&gt;:已调低顺序"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"显示在对话通知顶部(屏幕锁定时显示为个人资料照片)"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片)"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"优先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话功能"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"无法修改这些通知。"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短信"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音乐"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日历"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"勿扰"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"音量按钮快捷键"</string>
<string name="battery" msgid="769686279459897127">"电池"</string>
<string name="headset" msgid="4485892374984466437">"耳机"</string>
@@ -684,6 +697,10 @@
<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">"WLAN 已关闭"</string>
<string name="bt_is_off" msgid="7436344904889461591">"蓝牙已关闭"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"“勿扰”模式已关闭"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"某个自动规则(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"某个应用(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某个自动规则或应用已开启勿扰模式。"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"在后台运行的应用"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"点按即可详细了解电量和流量消耗情况"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"要关闭移动数据网络吗?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(工作)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"电话"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(通过“<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>”)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相机"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置信息"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麦克风"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已断开连接)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"无法切换。点按即可重试。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投射此会话,请打开相关应用。"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
<string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"查看近期的消息、未接电话和状态更新"</string>
<string name="people_tile_title" msgid="6589377493334871272">"对话"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"勿扰模式已暂停通知"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>发送了一条消息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>发送了一张图片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了状态:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 个使用中的应用</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 个使用中的应用</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"新信息"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的应用"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"已停止"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已复制"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"来自<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"关闭复制界面"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"修改所复制的文字"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"编辑所复制的图片"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"发送到附近的设备"</string>
+ <string name="add" msgid="81036585205287996">"添加"</string>
+ <string name="manage_users" msgid="1823875311934643849">"管理用户"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知不支持拖动到分屏中。"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN 已关闭"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"优先模式"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Google 助理访客模式已启用"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index dbb4ffc85d38..860085974d4f 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"系統使用者介面"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"電池電量可能即將耗盡"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"剩餘 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"無法透過 USB 充電"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"使用裝置隨附的充電器"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔已經驗證"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖案"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全靜音"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"只限鬧鐘"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"請勿騷擾。"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"藍牙。"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"藍牙已開啟。"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「請勿騷擾」模式已將通知暫停"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由您的家長管理"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;狀態:&lt;/b&gt;已調低次序"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片)"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片)"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短訊"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"請勿騷擾"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
<string name="battery" msgid="769686279459897127">"電池"</string>
<string name="headset" msgid="4485892374984466437">"耳機"</string>
@@ -684,6 +697,10 @@
<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 已關閉"</string>
<string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"「請勿騷擾」已關閉"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已開啟「請勿騷擾」功能。"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已開啟「請勿騷擾」功能。"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已開啟「請勿騷擾」功能。"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"正在背景中執行的應用程式"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"輕按即可查看電池和數據用量詳情"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉流動數據嗎?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(公司)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(透過「<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>」)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已中斷連線)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕按即可重試。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
<string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
<string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"「請勿騷擾」已暫停通知"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了圖片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>有狀態更新:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 個使用中的應用程式</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 個使用中的應用程式</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資料"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"已停止"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿使用者介面"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯已複製的文字"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯已複製的圖片"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送至附近的裝置"</string>
+ <string name="add" msgid="81036585205287996">"新增"</string>
+ <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知無法拖曳到分割螢幕中。"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"已啟用「Google 助理」訪客模式"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d7185a489e4b..0206a9e30360 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"系統 UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"電池電力可能很快就會耗盡"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"僅剩 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"無法透過 USB 充電"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"使用裝置隨附的充電器"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔驗證成功"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認完畢"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕觸 [確認] 完成驗證設定"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 碼"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用解鎖圖案"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全靜音"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"僅限鬧鐘"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"零打擾。"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"藍牙。"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"藍牙已開啟。"</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</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>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「零打擾」模式已將通知設為暫停"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;狀態:&lt;/b&gt;已調降順序"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片)"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片)"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"簡訊"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"零打擾"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
<string name="battery" msgid="769686279459897127">"電池"</string>
<string name="headset" msgid="4485892374984466437">"耳機"</string>
@@ -684,6 +697,10 @@
<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 已關閉"</string>
<string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"零打擾模式已關閉"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已將零打擾模式開啟。"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已將零打擾模式開啟。"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已將零打擾模式開啟。"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"在背景執行的應用程式"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"輕觸即可查看電池和數據用量詳情"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉行動數據嗎?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(工作)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(透過「<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>」)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(連線中斷)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕觸即可重試。"</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
<string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
<string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"零打擾模式已將通知暫停"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一則訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一張圖片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了狀態:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 個使用中的應用程式</item>
<item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 個使用中的應用程式</item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資訊"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"已停止"</string>
@@ -886,14 +907,17 @@
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿 UI"</string>
- <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
- <skip />
- <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
- <skip />
- <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
- <skip />
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯複製的文字"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯複製的圖片"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送到鄰近裝置"</string>
+ <string name="add" msgid="81036585205287996">"新增"</string>
+ <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"這項通知無法拖曳到分割畫面中。"</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"已啟用 Google 助理訪客模式"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 5425b268ba7d..98e7fc40e7ab 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -20,7 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"Uhlelo lwe-UI"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"Ibhethri lingaphela maduze"</string>
+ <!-- no translation found for battery_low_title (5319680173344341779) -->
+ <skip />
+ <!-- no translation found for battery_low_description (3282977755476423966) -->
+ <skip />
+ <!-- no translation found for battery_low_intro (5148725009653088790) -->
+ <skip />
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> okusele"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Ayikwazi ukushaja nge-USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Sebenzisa ishaja eze nedivayisi yakho"</string>
@@ -128,6 +133,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ubuso bufakazelwe ubuqiniso"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kuqinisekisiwe"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Sebenzisa iphinikhodi"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Sebenzisa iphethini"</string>
@@ -181,6 +188,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"Vala"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ukuthula okuphelele"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ama-alamu kuphela"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ungaphazamisi"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"I-Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"I-Bluetooth ivuliwe."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Isikhwama soswidi"</string>
<string name="start_dreams" msgid="9131802557946276718">"Isigcini sihenqo"</string>
<string name="ethernet_label" msgid="2203544727007463351">"I-Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ungaphazamisi"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"I-Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Awekho amadivayisi abhanqiwe atholakalayo"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string>
@@ -348,6 +357,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Izaziso"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sula zonke izaziso ezithulile"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
@@ -491,6 +501,8 @@
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Isimo:&lt;/b&gt; Silinganiselwe phansi"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ivela phezu kwezaziso zengxoxo nanjengesithombe sephrofayela esikrinini sokukhiya"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ukuphazamisa okuthi Ungaphazamisi"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza, ukuphazamisa okuthi Ungaphazamisi"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Okubalulekile"</string>
<string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
@@ -566,6 +578,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"I-SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Umculo"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ikhalenda"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ungaphazamisi"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Izinqamuleli zezinkinobho zevolomu"</string>
<string name="battery" msgid="769686279459897127">"Ibhethri"</string>
<string name="headset" msgid="4485892374984466437">"Ama-earphone"</string>
@@ -684,6 +697,10 @@
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"I-<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">"I-Wi-Fi ivaliwe"</string>
<string name="bt_is_off" msgid="7436344904889461591">"I-Bluetooth ivaliwe"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Ungaphazamisi kuvaliwe"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Okuthi ungaphazamisi kuvulwe uhlelo lokusebenza (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo noma uhlelo lokusebenza."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Vala idatha yeselula?"</string>
@@ -708,6 +725,8 @@
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(umsebenzi)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Ikholi yefoni"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kuya ku-<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ikhamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"indawo"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"imakrofoni"</string>
@@ -806,6 +825,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(inqamukile)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Akukwazi ukushintsha. Thepha ukuze uzame futhi."</string>
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
<string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
@@ -839,6 +860,7 @@
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Bona imiyalezo yakamuva, amakholi akuphuthile, nezibuyekezo zesimo"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Ingxoxo"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Kumiswe okuthi Ungaphazamisi"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele umlayezo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele isithombe"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"U-<xliff:g id="NAME">%1$s</xliff:g> unesibuyekezo sesimo: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
<item quantity="one">ama-app asebenzayo angu-<xliff:g id="COUNT_1">%s</xliff:g></item>
<item quantity="other">ama-app asebenzayo angu-<xliff:g id="COUNT_1">%s</xliff:g></item>
</plurals>
- <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
- <skip />
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ulwazi olusha"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ama-app asebenzayo"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Misa"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imisiwe"</string>
@@ -889,8 +910,14 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"Hlela umbhalo okopishiwe"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"Hlela umfanekiso okopishiwe"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Thumela kudivayisi eseduze"</string>
- <!-- no translation found for add (81036585205287996) -->
- <skip />
- <!-- no translation found for manage_users (1823875311934643849) -->
+ <string name="add" msgid="81036585205287996">"Faka"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Phatha abasebenzisi"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Lesi saziso asikusekeli ukuhudulela ku-Splitscreen."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"I-Wi-Fi ayitholakali"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imodi ebalulekile"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
+ <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Imodi yesivakashi somsizi inikwe amandla"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
+ <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index dc7470081da2..1edaaadfb433 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -52,7 +52,7 @@
(e.g. cannot be switched to) -->
<color name="kg_user_switcher_restricted_avatar_icon_color">@color/GM2_grey_600</color>
<!-- Color of background circle of user avatars in keyguard user switcher -->
- <color name="kg_user_switcher_avatar_background">?android:attr/colorBackgroundFloating</color>
+ <color name="user_avatar_color_bg">?android:attr/colorBackgroundFloating</color>
<!-- Icon color for user avatars in user switcher quick settings -->
<color name="qs_user_switcher_avatar_icon_color">#3C4043</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5a7efca3dece..5ca7285d3f73 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1122,13 +1122,40 @@
<dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
<dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen>
- <!-- Distance that the full shade transition takes in order for qs to fully transition to the
- shade -->
- <dimen name="lockscreen_shade_qs_transition_distance">200dp</dimen>
+ <!-- Distance that the full shade transition takes in order to complete by tapping on a button
+ like "expand". -->
+ <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
+
+ <!-- Distance that the full shade transition takes in order to complete. -->
+ <dimen name="lockscreen_shade_full_transition_distance">80dp</dimen>
<!-- Distance that the full shade transition takes in order for scrim to fully transition to
the shade (in alpha) -->
- <dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
+ <dimen name="lockscreen_shade_scrim_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the keyguard content on
+ NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
+ <dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the notification shelf to fully
+ expand. -->
+ <dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the Quick Settings to fully
+ fade and expand. -->
+ <dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
+ change. -->
+ <dimen name="lockscreen_shade_depth_controller_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+ fade. -->
+ <dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+ <!-- Used for StatusBar to know that a transition is in progress. At the moment it only checks
+ whether the progress is > 0, therefore this value is not very important. -->
+ <dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Distance that the full shade transition takes in order for media to fully transition to
the shade -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9e1f57bbfa75..9f2f1c1978c6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -66,7 +66,10 @@
<string name="battery_saver_confirmation_ok">Turn on</string>
<!-- Battery saver notification action [CHAR LIMIT=NONE]-->
- <string name="battery_saver_start_action">Turn on Battery Saver</string>
+ <string name="battery_saver_start_action">Turn on</string>
+
+ <!-- Battery saver notification dismiss action: Do not turn on battery saver. [CHAR LIMIT=NONE]-->
+ <string name="battery_saver_dismiss_action">No thanks</string>
<!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
@@ -2223,6 +2226,8 @@
<string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
<!-- App name when can't get app name [CHAR LIMIT=60] -->
<string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
+ <!-- Button text for stopping casting [CHAR LIMIT=60] -->
+ <string name="media_output_dialog_button_stop_casting">Stop casting</string>
<!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
@@ -2425,8 +2430,6 @@
<string name="dream_overlay_status_bar_priority_mode">Priority mode</string>
<!-- Content description for the alarm set icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
<string name="dream_overlay_status_bar_alarm_set">Alarm set</string>
- <!-- Content description for the assistant guest mode enabled icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
- <string name="dream_overlay_status_bar_assistant_guest_mode_enabled">Assistant guest mode enabled</string>
<!-- Content description for the camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
<string name="dream_overlay_status_bar_camera_mic_off">Camera and mic are off</string>
<!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/UiBackground.java b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java
index bf2237aa8c11..bf2237aa8c11 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/UiBackground.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index 98e48f64e9e6..b61827a0212c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -243,10 +243,15 @@ public class RemoteTransitionCompat implements Parcelable {
boolean merge(TransitionInfo info, SurfaceControl.Transaction t,
RecentsAnimationListener recents) {
ArrayList<TransitionInfo.Change> openingTasks = null;
+ boolean cancelRecents = false;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) {
if (change.getTaskInfo() != null) {
+ if (change.getTaskInfo().topActivityType == ACTIVITY_TYPE_HOME) {
+ // canceling recents animation
+ cancelRecents = true;
+ }
if (openingTasks == null) {
openingTasks = new ArrayList<>();
}
@@ -256,9 +261,11 @@ public class RemoteTransitionCompat implements Parcelable {
}
if (openingTasks == null) return false;
int pauseMatches = 0;
- for (int i = 0; i < openingTasks.size(); ++i) {
- if (mPausingTasks.contains(openingTasks.get(i).getContainer())) {
- ++pauseMatches;
+ if (!cancelRecents) {
+ for (int i = 0; i < openingTasks.size(); ++i) {
+ if (mPausingTasks.contains(openingTasks.get(i).getContainer())) {
+ ++pauseMatches;
+ }
}
}
if (pauseMatches > 0) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index ac62cf9f9d5b..15593ea5f0e4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -22,6 +22,7 @@ import android.hardware.SensorManager
import android.hardware.devicestate.DeviceStateManager
import android.os.Handler
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
@@ -53,6 +54,7 @@ internal interface UnfoldSharedComponent {
@BindsInstance sensorManager: SensorManager,
@BindsInstance @Main handler: Handler,
@BindsInstance @Main executor: Executor,
+ @BindsInstance @UiBackground backgroundExecutor: Executor,
@BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
@BindsInstance contentResolver: ContentResolver = context.contentResolver
): UnfoldSharedComponent
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 23e4c97fc271..c612995241ef 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.unfold
import android.hardware.SensorManager
+import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
@@ -30,6 +31,7 @@ import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
import dagger.Module
import dagger.Provides
import java.util.Optional
+import java.util.concurrent.Executor
import javax.inject.Singleton
@Module
@@ -67,10 +69,11 @@ class UnfoldSharedModule {
@Provides
fun hingeAngleProvider(
config: UnfoldTransitionConfig,
- sensorManager: SensorManager
+ sensorManager: SensorManager,
+ @UiBackground executor: Executor
): HingeAngleProvider =
if (config.isHingeAngleEnabled) {
- HingeSensorAngleProvider(sensorManager)
+ HingeSensorAngleProvider(sensorManager, executor)
} else {
EmptyHingeAngleProvider
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index d5d636208747..8e4ff9bc9133 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -42,6 +42,7 @@ fun createUnfoldTransitionProgressProvider(
sensorManager: SensorManager,
mainHandler: Handler,
mainExecutor: Executor,
+ backgroundExecutor: Executor,
tracingTagPrefix: String
): UnfoldTransitionProgressProvider =
DaggerUnfoldSharedComponent.factory()
@@ -53,6 +54,7 @@ fun createUnfoldTransitionProgressProvider(
sensorManager,
mainHandler,
mainExecutor,
+ backgroundExecutor,
tracingTagPrefix)
.unfoldTransitionProvider
.orElse(null)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
index a50d852e9b36..c93412b53817 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
@@ -6,21 +6,29 @@ import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Trace
import androidx.core.util.Consumer
+import java.util.concurrent.Executor
-internal class HingeSensorAngleProvider(private val sensorManager: SensorManager) :
+internal class HingeSensorAngleProvider(
+ private val sensorManager: SensorManager,
+ private val executor: Executor
+) :
HingeAngleProvider {
private val sensorListener = HingeAngleSensorListener()
private val listeners: MutableList<Consumer<Float>> = arrayListOf()
- override fun start() {
+ override fun start() = executor.execute {
Trace.beginSection("HingeSensorAngleProvider#start")
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
- sensorManager.registerListener(sensorListener, sensor, SensorManager.SENSOR_DELAY_FASTEST)
+ sensorManager.registerListener(
+ sensorListener,
+ sensor,
+ SensorManager.SENSOR_DELAY_FASTEST
+ )
Trace.endSection()
}
- override fun stop() {
+ override fun stop() = executor.execute {
sensorManager.unregisterListener(sensorListener)
}
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index c4b02f62f291..ffd15460ce91 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -107,10 +107,10 @@ public class EmergencyButton extends Button {
return super.performLongClick();
}
- void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) {
+ void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked) {
boolean visible = false;
- if (isVoiceCapable) {
- // Emergency calling requires voice capability.
+ if (hasTelephonyRadio) {
+ // Emergency calling requires a telephony radio.
if (isInCall) {
visible = true; // always show "return to call" if phone is off-hook
} else {
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
index e7215b8ebe49..f28910576073 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
@@ -21,6 +21,7 @@ import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -116,7 +117,8 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
if (mView != null) {
mView.updateEmergencyCallButton(
mTelecomManager != null && mTelecomManager.isInCall(),
- mTelephonyManager.isVoiceCapable(),
+ getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY),
mKeyguardUpdateMonitor.isSimPinVoiceSecure());
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 0529cdbcbb13..28f21af5b56b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -183,7 +183,7 @@ public class KeyguardPasswordViewController
@Override
void resetState() {
mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
- mMessageAreaController.setMessage("");
+ mMessageAreaController.setMessage(R.string.keyguard_enter_your_password);
final boolean wasDisabled = mPasswordEntry.isEnabled();
mView.setPasswordEntryEnabled(true);
mView.setPasswordEntryInputEnabled(true);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 41f92407a683..7635f919567a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -358,7 +358,7 @@ public class KeyguardPatternViewController
}
private void displayDefaultSecurityMessage() {
- mMessageAreaController.setMessage("");
+ mMessageAreaController.setMessage(R.string.keyguard_enter_your_pattern);
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index 8de4e7b557f3..a9c03d1ac08e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -132,5 +132,6 @@ public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinB
@Override
void resetState() {
mView.setPasswordEntryEnabled(true);
+ mMessageAreaController.setMessage(R.string.keyguard_enter_your_pin);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 9f4585fb1a92..160d82af98fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -76,12 +76,6 @@ public class KeyguardPinViewController
}
@Override
- void resetState() {
- super.resetState();
- mMessageAreaController.setMessage("");
- }
-
- @Override
public boolean startDisappearAnimation(Runnable finishRunnable) {
return mView.startDisappearAnimation(
mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index af7cf862b6b6..362fbed7055a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -918,7 +918,7 @@ public class KeyguardSecurityContainer extends FrameLayout {
}
drawable.setTint(iconColor);
- Drawable bg = context.getDrawable(R.drawable.kg_bg_avatar);
+ Drawable bg = context.getDrawable(R.drawable.user_avatar_bg);
bg.setTintBlendMode(BlendMode.DST);
bg.setTint(Utils.getColorAttrDefaultColor(context,
com.android.internal.R.attr.colorSurfaceVariant));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index a5fe0efc8887..af3da9f940bd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -20,7 +20,6 @@ import android.graphics.Rect;
import android.util.Slog;
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
-import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -63,7 +62,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
KeyguardClockSwitchController keyguardClockSwitchController,
KeyguardStateController keyguardStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- CommunalStateController communalStateController,
ConfigurationController configurationController,
DozeParameters dozeParameters,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -75,9 +73,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mConfigurationController = configurationController;
mDozeParameters = dozeParameters;
mKeyguardStateController = keyguardStateController;
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
- keyguardStateController, dozeParameters, screenOffAnimationController,
- /* animateYPos= */ true, /* visibleOnCommunal= */ false);
+ mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
+ dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 37f45644fa68..1ef6dea4e680 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -52,6 +52,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
+import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
@@ -752,15 +753,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void handleFingerprintAcquired(int acquireInfo) {
+ private void handleFingerprintAcquired(
+ @BiometricFingerprintConstants.FingerprintAcquired int acquireInfo) {
Assert.isMainThread();
- if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
- return;
- }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
+ cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT, acquireInfo);
}
}
}
@@ -960,14 +959,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private void handleFaceAcquired(int acquireInfo) {
Assert.isMainThread();
- if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
- return;
- }
- if (DEBUG_FACE) Log.d(TAG, "Face acquired");
+ if (DEBUG_FACE) Log.d(TAG, "Face acquired acquireInfo=" + acquireInfo);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onBiometricAcquired(BiometricSourceType.FACE);
+ cb.onBiometricAcquired(BiometricSourceType.FACE, acquireInfo);
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 8d5603dc1563..ad2053cbc31b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -206,8 +206,10 @@ public class KeyguardUpdateMonitorCallback {
* It is guaranteed that either {@link #onBiometricAuthenticated} or
* {@link #onBiometricAuthFailed(BiometricSourceType)} is called after this method eventually.
* @param biometricSourceType
+ * @param acquireInfo see {@link android.hardware.biometrics.BiometricFaceConstants} and
+ * {@link android.hardware.biometrics.BiometricFingerprintConstants}
*/
- public void onBiometricAcquired(BiometricSourceType biometricSourceType) { }
+ public void onBiometricAcquired(BiometricSourceType biometricSourceType, int acquireInfo) { }
/**
* Called when a biometric couldn't be authenticated.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index bb608c79a50e..498304b3fc55 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -22,7 +22,6 @@ import android.view.View;
import android.view.ViewPropertyAnimator;
import com.android.systemui.animation.Interpolators;
-import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -39,30 +38,24 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
public class KeyguardVisibilityHelper {
private View mView;
- private final CommunalStateController mCommunalStateController;
private final KeyguardStateController mKeyguardStateController;
private final DozeParameters mDozeParameters;
private final ScreenOffAnimationController mScreenOffAnimationController;
- private final boolean mVisibleOnCommunal;
private boolean mAnimateYPos;
private boolean mKeyguardViewVisibilityAnimating;
private boolean mLastOccludedState = false;
private final AnimationProperties mAnimationProperties = new AnimationProperties();
public KeyguardVisibilityHelper(View view,
- CommunalStateController communalStateController,
KeyguardStateController keyguardStateController,
DozeParameters dozeParameters,
ScreenOffAnimationController screenOffAnimationController,
- boolean animateYPos,
- boolean visibleOnCommunal) {
+ boolean animateYPos) {
mView = view;
- mCommunalStateController = communalStateController;
mKeyguardStateController = keyguardStateController;
mDozeParameters = dozeParameters;
mScreenOffAnimationController = screenOffAnimationController;
mAnimateYPos = animateYPos;
- mVisibleOnCommunal = visibleOnCommunal;
}
public boolean isVisibilityAnimating() {
@@ -81,13 +74,6 @@ public class KeyguardVisibilityHelper {
boolean isOccluded = mKeyguardStateController.isOccluded();
mKeyguardViewVisibilityAnimating = false;
- // If the communal view is showing, hide immediately
- if (!mVisibleOnCommunal && mCommunalStateController.getCommunalViewShowing()) {
- mView.setVisibility(View.GONE);
- mView.setAlpha(1f);
- return;
- }
-
if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
&& statusBarState != KEYGUARD) || goingToFullShade) {
mKeyguardViewVisibilityAnimating = true;
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index 00470c0efe35..f925eaa0e40b 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -73,12 +73,14 @@ class NumPadAnimator {
ValueAnimator expandBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
mNormalColor, mHighlightColor);
expandBackgroundColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
+ expandBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
expandBackgroundColorAnimator.addUpdateListener(
animator -> mBackground.setColor((int) animator.getAnimatedValue()));
ValueAnimator expandTextColorAnimator =
ValueAnimator.ofObject(new ArgbEvaluator(),
textColorPrimary, textColorPrimaryInverse);
+ expandTextColorAnimator.setInterpolator(Interpolators.LINEAR);
expandTextColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
expandTextColorAnimator.addUpdateListener(valueAnimator -> {
if (digitTextView != null) {
@@ -98,6 +100,7 @@ class NumPadAnimator {
anim -> mBackground.setCornerRadius((float) anim.getAnimatedValue()));
ValueAnimator contractBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
mHighlightColor, mNormalColor);
+ contractBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
contractBackgroundColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
contractBackgroundColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
contractBackgroundColorAnimator.addUpdateListener(
@@ -106,6 +109,7 @@ class NumPadAnimator {
ValueAnimator contractTextColorAnimator =
ValueAnimator.ofObject(new ArgbEvaluator(), textColorPrimaryInverse,
textColorPrimary);
+ contractTextColorAnimator.setInterpolator(Interpolators.LINEAR);
contractTextColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
contractTextColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
contractTextColorAnimator.addUpdateListener(valueAnimator -> {
diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
index bc2a1ff24235..7afd43d1cb06 100644
--- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java
+++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.os.Build;
@@ -78,7 +79,8 @@ public class LatencyTester extends CoreStartable {
}
private void fakeWakeAndUnlock(BiometricSourceType type) {
- mBiometricUnlockController.onBiometricAcquired(type);
+ mBiometricUnlockController.onBiometricAcquired(type,
+ BiometricConstants.BIOMETRIC_ACQUIRED_GOOD);
mBiometricUnlockController.onBiometricAuthenticated(
KeyguardUpdateMonitor.getCurrentUser(), type, true /* isStrongBiometric */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 6a60afa8eadf..ff5715c606b6 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -71,7 +71,9 @@ public final class Prefs {
Key.HAS_SEEN_REVERSE_BOTTOM_SHEET,
Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT,
Key.HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP,
- Key.ACCESSIBILITY_FLOATING_MENU_POSITION
+ Key.ACCESSIBILITY_FLOATING_MENU_POSITION,
+ Key.HAS_CLICKED_NUDGE_TO_SETUP_DREAM,
+ Key.HAS_DISMISSED_NUDGE_TO_SETUP_DREAM
})
// TODO: annotate these with their types so {@link PrefsCommandLine} can know how to set them
public @interface Key {
@@ -115,6 +117,8 @@ public final class Prefs {
String HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP =
"HasSeenAccessibilityFloatingMenuDockTooltip";
String ACCESSIBILITY_FLOATING_MENU_POSITION = "AccessibilityFloatingMenuPosition";
+ String HAS_CLICKED_NUDGE_TO_SETUP_DREAM = "HasClickedNudgeToSetupDream";
+ String HAS_DISMISSED_NUDGE_TO_SETUP_DREAM = "HasDismissedNudgeToSetupDream";
}
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 50ca447090b5..7e1a02626dc9 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -1072,6 +1072,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
pw.println("WindowMagnificationController (displayId=" + mDisplayId + "):");
pw.println(" mOverlapWithGestureInsets:" + mOverlapWithGestureInsets);
pw.println(" mScale:" + mScale);
+ pw.println(" mWindowBounds:" + mWindowBounds);
pw.println(" mMirrorViewBounds:" + (isWindowVisible() ? mMirrorViewBounds : "empty"));
pw.println(" mMagnificationFrameBoundary:"
+ (isWindowVisible() ? mMagnificationFrameBoundary : "empty"));
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 99f27d7f48e7..a27b9cd357f4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PointF
+import android.hardware.biometrics.BiometricFingerprintConstants
import android.hardware.biometrics.BiometricSourceType
import android.util.DisplayMetrics
import android.util.Log
@@ -39,8 +40,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.BiometricUnlockController
-import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -257,6 +258,16 @@ class AuthRippleController @Inject constructor(
override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
mView.retractRipple()
}
+
+ override fun onBiometricAcquired(
+ biometricSourceType: BiometricSourceType?,
+ acquireInfo: Int
+ ) {
+ if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
+ acquireInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL) {
+ mView.retractRipple()
+ }
+ }
}
private val configurationChangedListener =
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 8052c2071d86..bf42db53d3d8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
import static com.android.internal.util.Preconditions.checkArgument;
@@ -30,6 +31,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Point;
import android.graphics.RectF;
+import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.SensorLocationInternal;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
@@ -141,11 +143,11 @@ public class UdfpsController implements DozeReceiver {
private int mActivePointerId = -1;
// The timestamp of the most recent touch log.
private long mTouchLogTime;
- // Sensor has a good capture for this touch. Do not need to illuminate for this particular
- // touch event anymore. In other words, do not illuminate until user lifts and touches the
- // sensor area again.
+ // Sensor has a capture (good or bad) for this touch. Do not need to illuminate for this
+ // particular touch event anymore. In other words, do not illuminate until user lifts and
+ // touches the sensor area again.
// TODO: We should probably try to make touch/illumination things more of a FSM
- private boolean mGoodCaptureReceived;
+ private boolean mAcquiredReceived;
// The current request from FingerprintService. Null if no current request.
@Nullable UdfpsControllerOverlay mOverlay;
@@ -221,19 +223,28 @@ public class UdfpsController implements DozeReceiver {
}
@Override
- public void onAcquiredGood(int sensorId) {
- mFgExecutor.execute(() -> {
- if (mOverlay == null) {
- Log.e(TAG, "Null request when onAcquiredGood for sensorId: " + sensorId);
- return;
- }
- mGoodCaptureReceived = true;
- final UdfpsView view = mOverlay.getOverlayView();
- if (view != null) {
- view.stopIllumination();
- }
- mOverlay.onAcquiredGood();
- });
+ public void onAcquired(
+ int sensorId,
+ @BiometricFingerprintConstants.FingerprintAcquired int acquiredInfo
+ ) {
+ if (BiometricFingerprintConstants.shouldTurnOffHbm(acquiredInfo)) {
+ boolean acquiredGood = acquiredInfo == FINGERPRINT_ACQUIRED_GOOD;
+ mFgExecutor.execute(() -> {
+ if (mOverlay == null) {
+ Log.e(TAG, "Null request when onAcquired for sensorId: " + sensorId
+ + " acquiredInfo=" + acquiredInfo);
+ return;
+ }
+ mAcquiredReceived = true;
+ final UdfpsView view = mOverlay.getOverlayView();
+ if (view != null) {
+ view.stopIllumination(); // turn off HBM
+ }
+ if (acquiredGood) {
+ mOverlay.onAcquiredGood();
+ }
+ });
+ }
}
@Override
@@ -414,8 +425,8 @@ public class UdfpsController implements DozeReceiver {
"minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
minor, major, v, exceedsVelocityThreshold);
final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
- if (!isIlluminationRequested && !mGoodCaptureReceived &&
- !exceedsVelocityThreshold) {
+ if (!isIlluminationRequested && !mAcquiredReceived
+ && !exceedsVelocityThreshold) {
final int rawX = (int) event.getRawX();
final int rawY = (int) event.getRawY();
// Default coordinates assume portrait mode.
@@ -799,7 +810,7 @@ public class UdfpsController implements DozeReceiver {
private void onFingerUp(@NonNull UdfpsView view) {
mExecution.assertIsMainThread();
mActivePointerId = -1;
- mGoodCaptureReceived = false;
+ mAcquiredReceived = false;
if (mOnFingerDown) {
mFingerprintManager.onPointerUp(mSensorProps.sensorId);
for (Callback cb : mCallbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index a17ddc89818d..56e4d7ec1882 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -166,7 +166,7 @@ public class ClipboardOverlayController {
mRemoteCopyChip = requireNonNull(mView.findViewById(R.id.remote_copy_chip));
mDismissButton = requireNonNull(mView.findViewById(R.id.dismiss_button));
- mView.setOnDismissCallback(this::hideImmediate);
+ mView.setOnDismissEndCallback(this::hideImmediate);
mView.setOnInteractionCallback(mTimeoutHandler::resetTimeout);
mDismissButton.setOnClickListener(view -> animateOut());
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
index 8843462413b5..57dc1620a410 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
@@ -16,25 +16,32 @@
package com.android.systemui.clipboardoverlay;
+import android.animation.Animator;
import android.content.Context;
import android.graphics.Rect;
+import android.graphics.Region;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewTreeObserver;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.systemui.R;
import com.android.systemui.screenshot.SwipeDismissHandler;
+import java.util.function.Consumer;
+
/**
* ConstraintLayout that is draggable when touched in a specific region
*/
-public class DraggableConstraintLayout extends ConstraintLayout {
+public class DraggableConstraintLayout extends ConstraintLayout
+ implements ViewTreeObserver.OnComputeInternalInsetsListener {
private final SwipeDismissHandler mSwipeDismissHandler;
private final GestureDetector mSwipeDetector;
- private Runnable mOnDismiss;
+ private Consumer<Animator> mOnDismissInitiated;
+ private Runnable mOnDismissComplete;
private Runnable mOnInteraction;
public DraggableConstraintLayout(Context context) {
@@ -58,9 +65,16 @@ public class DraggableConstraintLayout extends ConstraintLayout {
}
@Override
- public void onDismiss() {
- if (mOnDismiss != null) {
- mOnDismiss.run();
+ public void onSwipeDismissInitiated(Animator animator) {
+ if (mOnDismissInitiated != null) {
+ mOnDismissInitiated.accept(animator);
+ }
+ }
+
+ @Override
+ public void onDismissComplete() {
+ if (mOnDismissComplete != null) {
+ mOnDismissComplete.run();
}
}
});
@@ -84,11 +98,6 @@ public class DraggableConstraintLayout extends ConstraintLayout {
mSwipeDetector.setIsLongpressEnabled(false);
}
- @Override // View
- protected void onFinishInflate() {
-
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
@@ -106,10 +115,18 @@ public class DraggableConstraintLayout extends ConstraintLayout {
}
/**
+ * Set the callback to be run after view is dismissed (before animation; receives animator as
+ * input)
+ */
+ public void setOnDismissStartCallback(Consumer<Animator> callback) {
+ mOnDismissInitiated = callback;
+ }
+
+ /**
* Set the callback to be run after view is dismissed
*/
- public void setOnDismissCallback(Runnable callback) {
- mOnDismiss = callback;
+ public void setOnDismissEndCallback(Runnable callback) {
+ mOnDismissComplete = callback;
}
/**
@@ -118,4 +135,29 @@ public class DraggableConstraintLayout extends ConstraintLayout {
public void setOnInteractionCallback(Runnable callback) {
mOnInteraction = callback;
}
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
+ // Only child views are touchable.
+ Region r = new Region();
+ Rect rect = new Rect();
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).getGlobalVisibleRect(rect);
+ r.op(rect, Region.Op.UNION);
+ }
+ inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ inoutInfo.touchableRegion.set(r);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java
deleted file mode 100644
index 6e2fcd11f643..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Container for communal presentation. Containing communal-related view to this parent view allows
- * for aggregate measurement/layout adjustments and capturing said values before the communal views
- * might be available.
- */
-public class CommunalHostView extends FrameLayout {
- public CommunalHostView(@NonNull Context context) {
- this(context, null, 0);
- }
-
- public CommunalHostView(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public CommunalHostView(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java
deleted file mode 100644
index b42838099986..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.KeyguardVisibilityHelper;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.AnimatableProperty;
-import com.android.systemui.statusbar.notification.PropertyAnimator;
-import com.android.systemui.statusbar.notification.stack.AnimationProperties;
-import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.ViewController;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * Injectable controller for {@link CommunalHostView}.
- */
-public class CommunalHostViewController extends ViewController<CommunalHostView> {
- private static final String TAG = "CommunalController";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String STATE_LIST_FORMAT = "[%s]";
- private static final AnimationProperties COMMUNAL_ANIMATION_PROPERTIES =
- new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-
- private final Executor mMainExecutor;
- private final CommunalStateController mCommunalStateController;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final KeyguardStateController mKeyguardStateController;
- private final StatusBarStateController mStatusBarStateController;
- private WeakReference<CommunalSource> mCurrentSource;
- private Optional<ShowRequest> mLastRequest = Optional.empty();
- private int mState;
- private float mQsExpansion;
- private float mShadeExpansion;
-
- @Retention(RetentionPolicy.RUNTIME)
- @IntDef({STATE_KEYGUARD_SHOWING, STATE_DOZING, STATE_BOUNCER_SHOWING, STATE_KEYGUARD_OCCLUDED})
- public @interface State {}
-
- private static final int STATE_KEYGUARD_SHOWING = 1 << 0;
- private static final int STATE_DOZING = 1 << 1;
- private static final int STATE_BOUNCER_SHOWING = 1 << 2;
- private static final int STATE_KEYGUARD_OCCLUDED = 1 << 3;
-
- // Only show communal view when keyguard is showing and not dozing.
- private static final int SHOW_COMMUNAL_VIEW_REQUIRED_STATES = STATE_KEYGUARD_SHOWING;
- private static final int SHOW_COMMUNAL_VIEW_INVALID_STATES =
- STATE_DOZING | STATE_KEYGUARD_OCCLUDED;
-
- private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
-
- private ViewController<? extends View> mCommunalViewController;
-
- private static class ShowRequest {
- private boolean mShouldShow;
- private WeakReference<CommunalSource> mSource;
-
- ShowRequest(boolean shouldShow, WeakReference<CommunalSource> source) {
- mShouldShow = shouldShow;
- mSource = source;
- }
-
- CommunalSource getSource() {
- return mSource != null ? mSource.get() : null;
- }
-
- boolean shouldShow() {
- return mShouldShow;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ShowRequest)) return false;
- ShowRequest that = (ShowRequest) o;
- return mShouldShow == that.mShouldShow && Objects.equals(getSource(), that.getSource());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mShouldShow, mSource);
- }
- }
-
- private KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
- if (DEBUG) {
- Log.d(TAG, "onKeyguardBouncerChanged:" + bouncer);
- }
-
- setState(STATE_BOUNCER_SHOWING, bouncer);
- }
-
- @Override
- public void onKeyguardOccludedChanged(boolean occluded) {
- if (DEBUG) {
- Log.d(TAG, "onKeyguardOccludedChanged" + occluded);
- }
-
- setState(STATE_KEYGUARD_OCCLUDED, occluded);
- }
- };
-
- private KeyguardStateController.Callback mKeyguardCallback =
- new KeyguardStateController.Callback() {
- @Override
- public void onKeyguardShowingChanged() {
- final boolean isShowing = mKeyguardStateController.isShowing();
- if (DEBUG) {
- Log.d(TAG, "setKeyguardShowing:" + isShowing);
- }
-
- setState(STATE_KEYGUARD_SHOWING, isShowing);
- }
- };
-
- private StatusBarStateController.StateListener mDozeCallback =
- new StatusBarStateController.StateListener() {
- @Override
- public void onDozingChanged(boolean isDozing) {
- if (DEBUG) {
- Log.d(TAG, "setDozing:" + isDozing);
- }
-
- setState(STATE_DOZING, isDozing);
- }
-
- @Override
- public void onStateChanged(int newState) {
- updateCommunalViewOccluded();
- }
- };
-
- @Inject
- protected CommunalHostViewController(@Main Executor mainExecutor,
- CommunalStateController communalStateController,
- KeyguardUpdateMonitor keyguardUpdateMonitor,
- KeyguardStateController keyguardStateController,
- DozeParameters dozeParameters,
- ScreenOffAnimationController screenOffAnimationController,
- StatusBarStateController statusBarStateController, CommunalHostView view) {
- super(view);
- mCommunalStateController = communalStateController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mMainExecutor = mainExecutor;
- mKeyguardStateController = keyguardStateController;
- mStatusBarStateController = statusBarStateController;
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
- keyguardStateController, dozeParameters, screenOffAnimationController,
- /* animateYPos= */ false, /* visibleOnCommunal= */ true);
- }
-
- /**
- * Set the visibility of the keyguard status view based on some new state.
- */
- public void setKeyguardStatusViewVisibility(
- int statusBarState,
- boolean keyguardFadingAway,
- boolean goingToFullShade,
- int oldStatusBarState) {
- mKeyguardVisibilityHelper.setViewVisibility(
- statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState);
- }
-
- /**
- * Set keyguard status view alpha.
- */
- public void setAlpha(float alpha) {
- if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
- mView.setAlpha(alpha);
-
- // Some communal view implementations, such as SurfaceViews, do not behave correctly
- // inheriting the alpha of their parent. Directly set child alpha here to work around
- // this.
- for (int i = mView.getChildCount() - 1; i >= 0; --i) {
- mView.getChildAt(i).setAlpha(alpha);
- }
- }
- }
- @Override
- public void onInit() {
- setState(STATE_KEYGUARD_SHOWING, mKeyguardStateController.isShowing());
- setState(STATE_DOZING, mStatusBarStateController.isDozing());
- }
-
- @Override
- protected void onViewAttached() {
- mKeyguardStateController.addCallback(mKeyguardCallback);
- mStatusBarStateController.addCallback(mDozeCallback);
- mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
- }
-
- @Override
- protected void onViewDetached() {
- mKeyguardStateController.removeCallback(mKeyguardCallback);
- mStatusBarStateController.removeCallback(mDozeCallback);
- mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
- }
-
- private void setState(@State int stateFlag, boolean enabled) {
- final int existingState = mState;
- if (DEBUG) {
- Log.d(TAG, "setState flag:" + describeState(stateFlag) + " enabled:" + enabled);
- }
-
- if (enabled) {
- mState |= stateFlag;
- } else {
- mState &= ~stateFlag;
- }
-
- if (DEBUG) {
- Log.d(TAG, "updated state:" + describeState());
- }
-
- if (existingState != mState) {
- showSource();
- }
-
- updateCommunalViewOccluded();
- }
-
- private String describeState(@State int stateFlag) {
- switch(stateFlag) {
- case STATE_DOZING:
- return "dozing";
- case STATE_BOUNCER_SHOWING:
- return "bouncer_showing";
- case STATE_KEYGUARD_SHOWING:
- return "keyguard_showing";
- default:
- return "UNDEFINED_STATE";
- }
- }
-
- private String describeState() {
- StringBuilder stringBuilder = new StringBuilder();
-
- if ((mState & STATE_KEYGUARD_SHOWING) == STATE_KEYGUARD_SHOWING) {
- stringBuilder.append(String.format(STATE_LIST_FORMAT,
- describeState(STATE_KEYGUARD_SHOWING)));
- }
- if ((mState & STATE_DOZING) == STATE_DOZING) {
- stringBuilder.append(String.format(STATE_LIST_FORMAT,
- describeState(STATE_DOZING)));
- }
- if ((mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING) {
- stringBuilder.append(String.format(STATE_LIST_FORMAT,
- describeState(STATE_BOUNCER_SHOWING)));
- }
-
- return stringBuilder.toString();
- }
-
- private void showSource() {
- final ShowRequest request = new ShowRequest(
- (mState & SHOW_COMMUNAL_VIEW_REQUIRED_STATES) == SHOW_COMMUNAL_VIEW_REQUIRED_STATES
- && (mState & SHOW_COMMUNAL_VIEW_INVALID_STATES) == 0
- && mCurrentSource != null,
- mCurrentSource);
-
- if (mLastRequest.isPresent() && Objects.equals(mLastRequest.get(), request)) {
- return;
- }
-
- mLastRequest = Optional.of(request);
-
- // Make sure all necessary states are present for showing communal and all invalid states
- // are absent
- mMainExecutor.execute(() -> {
- if (DEBUG) {
- Log.d(TAG, "showSource. currentSource:" + request.getSource());
- }
-
- if (request.shouldShow()) {
- mView.removeAllViews();
-
- // Make view visible.
- mView.setVisibility(View.VISIBLE);
-
- final Context context = mView.getContext();
-
- final ListenableFuture<CommunalSource.CommunalViewResult> listenableFuture =
- request.getSource().requestCommunalView(context);
-
- if (listenableFuture == null) {
- Log.e(TAG, "could not request communal view");
- return;
- }
-
- listenableFuture.addListener(() -> {
- try {
- final CommunalSource.CommunalViewResult result = listenableFuture.get();
- result.view.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT));
- mView.addView(result.view);
-
- mCommunalViewController = result.viewController;
- mCommunalViewController.init();
- } catch (Exception e) {
- Log.e(TAG, "could not obtain communal view through callback:" + e);
- }
- }, mMainExecutor);
- } else {
- mView.removeAllViews();
- mView.setVisibility(View.INVISIBLE);
- mCommunalStateController.setCommunalViewShowing(false);
- }
- });
- }
-
- /**
- * Instructs {@link CommunalHostViewController} to display provided source.
- *
- * @param source The new {@link CommunalSource}, {@code null} if not set.
- */
- public void show(WeakReference<CommunalSource> source) {
- mCurrentSource = source;
- showSource();
- }
-
- /**
- * Update position of the view with an optional animation
- */
- public void updatePosition(int y, boolean animate) {
- PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, COMMUNAL_ANIMATION_PROPERTIES,
- animate);
- }
-
- /**
- * Invoked when the quick settings is expanded.
- * @param expansionFraction the percentage the QS shade has been expanded.
- */
- public void updateQsExpansion(float expansionFraction) {
- mQsExpansion = expansionFraction;
- updateCommunalViewOccluded();
- }
-
- /**
- * Invoked when the main shade is expanded.
- * @param shadeExpansion the percentage the main shade has expanded.
- */
- public void updateShadeExpansion(float shadeExpansion) {
- mShadeExpansion = shadeExpansion;
- updateCommunalViewOccluded();
- }
-
- private void updateCommunalViewOccluded() {
- final boolean bouncerShowing = (mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING;
- final int statusBarState = mStatusBarStateController.getState();
- final boolean shadeExpanded = statusBarState == StatusBarState.SHADE
- || statusBarState == StatusBarState.SHADE_LOCKED;
-
- mCommunalStateController.setCommunalViewOccluded(
- bouncerShowing || shadeExpanded || mQsExpansion > 0.0f || mShadeExpansion > 0.0f);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java
deleted file mode 100644
index 424da0b111c5..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.util.Log;
-
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-
-/**
- * {@link CommunalHostViewPositionAlgorithm} calculates the position of the communal view given
- * input such as the notification panel position.
- */
-public class CommunalHostViewPositionAlgorithm {
- private static final String TAG = "CommunalPositionAlg";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- /**
- * @see NotificationPanelViewController#getExpandedFraction()
- */
- private float mPanelExpansion;
-
- /**
- * Height of {@link CommunalHostView}.
- */
- private int mCommunalHeight;
-
- /**
- * A data container for the result of the position algorithm.
- */
- public static class Result {
- /**
- * The y translation of the clock.
- */
- public int communalY;
- }
-
- /**
- * Sets the conditions under which the result should be calculated from.
- * @param panelExpansion The percentage the keyguard panel has been moved upwards.
- * @param communalHeight The height of the communal panel.
- */
- public void setup(float panelExpansion, int communalHeight) {
- if (DEBUG) {
- Log.d(TAG, "setup. panelExpansion:" + panelExpansion);
- }
- mPanelExpansion = panelExpansion;
- mCommunalHeight = communalHeight;
- }
-
- /**
- * Calculates the position based on factors input through {link {@link #setup(float, int)}}.
- * @param result The resulting calculations.
- */
- public void run(Result result) {
- // The panel expansion relates to the keyguard expansion. At full expansion, the communal
- // view should be aligned at the top (0). Otherwise, it should be shifted offscreen by the
- // unexpanded amount.
- result.communalY = (int) ((1 - mPanelExpansion) * -mCommunalHeight);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java
deleted file mode 100644
index 42ecd5c835bb..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.systemui.util.ViewController;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.util.Optional;
-
-/**
- * {@link CommunalSource} defines an interface for working with a source for communal data. Clients
- * may request a communal surface that can be shown within a {@link android.view.SurfaceView}.
- * Callbacks may also be registered to listen to state changes.
- */
-public interface CommunalSource {
- /**
- * {@link Connector} defines an interface for {@link CommunalSource} instances to be generated.
- */
- interface Connector {
- Connection connect(Connection.Callback callback);
- }
-
- /**
- * {@link Connection} defines an interface for an entity which holds the necessary components
- * for establishing and maintaining a connection to the communal source.
- */
- interface Connection {
- /**
- * {@link Callback} defines an interface for clients to be notified when a source is ready
- */
- interface Callback {
- void onSourceEstablished(Optional<CommunalSource> source);
- void onDisconnected();
- }
-
- void disconnect();
- }
-
- /**
- * The {@link Observer} interface specifies an entity which {@link CommunalSource} listeners
- * can be informed of changes to the source, which will require updating. Note that this deals
- * with changes to the source itself, not content which will be updated through the
- * {@link CommunalSource} interface.
- */
- interface Observer {
- interface Callback {
- void onSourceChanged();
- }
-
- void addCallback(Callback callback);
- void removeCallback(Callback callback);
- }
-
- /**
- * {@link CommunalViewResult} is handed back from {@link #requestCommunalView(Context)} and
- * contains the view to be displayed and its associated controller.
- */
- class CommunalViewResult {
- /**
- * The resulting communal view.
- */
- public final View view;
- /**
- * The controller for the communal view.
- */
- public final ViewController<? extends View> viewController;
-
- /**
- * The default constructor for {@link CommunalViewResult}.
- * @param view The communal view.
- * @param viewController The communal view's controller.
- */
- public CommunalViewResult(View view, ViewController<? extends View> viewController) {
- this.view = view;
- this.viewController = viewController;
- }
- }
-
- /**
- * Requests a communal surface that can be displayed inside {@link CommunalHostView}.
- *
- * @param context The {@link View} {@link Context} to build the resulting view from
- * @return A future that can be listened upon for the resulting {@link CommunalViewResult}. The
- * value will be {@code null} in case of a failure.
- */
- ListenableFuture<CommunalViewResult> requestCommunalView(Context context);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java
deleted file mode 100644
index 58cf35f2917c..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.android.systemui.communal.dagger.CommunalModule.COMMUNAL_CONDITIONS;
-
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.condition.Monitor;
-
-import com.google.android.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * A Monitor for reporting a {@link CommunalSource} presence.
- */
-@SysUISingleton
-public class CommunalSourceMonitor {
- private static final String TAG = "CommunalSourceMonitor";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- // A list of {@link Callback} that have registered to receive updates.
- private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
- private final Monitor mConditionsMonitor;
- private final Executor mExecutor;
-
- private CommunalSource mCurrentSource;
-
- // Whether all conditions for communal mode to show have been met.
- private boolean mAllCommunalConditionsMet = false;
-
- // Whether the class is currently listening for condition changes.
- private boolean mListeningForConditions = false;
-
- private final Monitor.Callback mConditionsCallback =
- allConditionsMet -> {
- if (mAllCommunalConditionsMet != allConditionsMet) {
- if (DEBUG) Log.d(TAG, "communal conditions changed: " + allConditionsMet);
-
- mAllCommunalConditionsMet = allConditionsMet;
- executeOnSourceAvailableCallbacks();
- }
- };
-
- @VisibleForTesting
- @Inject
- public CommunalSourceMonitor(@Main Executor executor,
- @Named(COMMUNAL_CONDITIONS) Monitor communalConditionsMonitor) {
- mExecutor = executor;
- mConditionsMonitor = communalConditionsMonitor;
- }
-
- /**
- * Sets the current {@link CommunalSource}, informing any callbacks. Any existing
- * {@link CommunalSource} will be disconnected.
- *
- * @param source The new {@link CommunalSource}.
- */
- public void setSource(CommunalSource source) {
- mCurrentSource = source;
-
- if (mAllCommunalConditionsMet) {
- executeOnSourceAvailableCallbacks();
- }
- }
-
- private void executeOnSourceAvailableCallbacks() {
- mExecutor.execute(() -> {
- // If the new source is valid, inform registered Callbacks of its presence.
- Iterator<WeakReference<Callback>> itr = mCallbacks.iterator();
- while (itr.hasNext()) {
- Callback cb = itr.next().get();
- if (cb == null) {
- itr.remove();
- } else {
- cb.onSourceAvailable(
- (mAllCommunalConditionsMet && mCurrentSource != null)
- ? new WeakReference<>(mCurrentSource) : null);
- }
- }
- });
- }
-
- /**
- * Adds a {@link Callback} to receive {@link CommunalSource} updates.
- *
- * @param callback The {@link Callback} to add.
- */
- public void addCallback(Callback callback) {
- mExecutor.execute(() -> {
- mCallbacks.add(new WeakReference<>(callback));
-
- // Inform the callback of any already present CommunalSource.
- if (mAllCommunalConditionsMet && mCurrentSource != null) {
- callback.onSourceAvailable(new WeakReference<>(mCurrentSource));
- }
-
- if (!mListeningForConditions) {
- mConditionsMonitor.addCallback(mConditionsCallback);
- mListeningForConditions = true;
- }
- });
- }
-
- /**
- * Removes the specified {@link Callback} from receive future updates if present.
- *
- * @param callback The {@link Callback} to add.
- */
- public void removeCallback(Callback callback) {
- mExecutor.execute(() -> {
- mCallbacks.removeIf(el -> el.get() == callback);
-
- if (mCallbacks.isEmpty() && mListeningForConditions) {
- mConditionsMonitor.removeCallback(mConditionsCallback);
- mListeningForConditions = false;
- }
- });
- }
-
- /**
- * Interface implemented to be notified when new {@link CommunalSource} become available.
- */
- public interface Callback {
- /**
- * Called when a new {@link CommunalSource} has been registered. This will also be invoked
- * when a {@link Callback} is first registered and a {@link CommunalSource} is already
- * registered.
- *
- * @param source The new {@link CommunalSource}.
- */
- void onSourceAvailable(WeakReference<CommunalSource> source);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java
deleted file mode 100644
index f965431a8001..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.time.SystemClock;
-
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-/**
- * The {@link CommunalSourcePrimer} is responsible for priming SystemUI with a pre-configured
- * Communal source. The SystemUI service binds to the component to retrieve the
- * {@link CommunalSource}. {@link CommunalSourcePrimer} has no effect
- * if there is no pre-defined value.
- */
-@SysUISingleton
-public class CommunalSourcePrimer extends CoreStartable {
- private static final String TAG = "CommunalSourcePrimer";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final SystemClock mSystemClock;
- private final DelayableExecutor mMainExecutor;
- private final CommunalSourceMonitor mMonitor;
- private final int mBaseReconnectDelayMs;
- private final int mMaxReconnectAttempts;
- private final int mMinConnectionDuration;
-
- private int mReconnectAttempts = 0;
- private Runnable mCurrentReconnectCancelable;
-
- private final Optional<CommunalSource.Observer> mObserver;
- private final Optional<CommunalSource.Connector> mConnector;
-
- private CommunalSource.Connection mCurrentConnection;
-
- private final Runnable mConnectRunnable = new Runnable() {
- @Override
- public void run() {
- mCurrentReconnectCancelable = null;
- connect();
- }
- };
-
- private final CommunalSource.Observer.Callback mObserverCallback = () -> {
- initiateConnectionAttempt();
- };
-
- @Inject
- public CommunalSourcePrimer(Context context, @Main Resources resources,
- SystemClock clock,
- DelayableExecutor mainExecutor,
- CommunalSourceMonitor monitor,
- Optional<CommunalSource.Connector> connector,
- Optional<CommunalSource.Observer> observer) {
- super(context);
- mSystemClock = clock;
- mMainExecutor = mainExecutor;
- mMonitor = monitor;
- mConnector = connector;
- mObserver = observer;
-
- mMaxReconnectAttempts = resources.getInteger(
- R.integer.config_communalSourceMaxReconnectAttempts);
- mBaseReconnectDelayMs = resources.getInteger(
- R.integer.config_communalSourceReconnectBaseDelay);
- mMinConnectionDuration = resources.getInteger(
- R.integer.config_connectionMinDuration);
- }
-
- @Override
- public void start() {
- }
-
- private void initiateConnectionAttempt() {
- // Reset attempts
- mReconnectAttempts = 0;
- mMonitor.setSource(null);
-
- // The first attempt is always a direct invocation rather than delayed.
- connect();
- }
-
- private void scheduleConnectionAttempt() {
- // always clear cancelable if present.
- if (mCurrentReconnectCancelable != null) {
- mCurrentReconnectCancelable.run();
- mCurrentReconnectCancelable = null;
- }
-
- if (mReconnectAttempts >= mMaxReconnectAttempts) {
- if (DEBUG) {
- Log.d(TAG, "exceeded max connection attempts.");
- }
- return;
- }
-
- final long reconnectDelayMs =
- (long) Math.scalb(mBaseReconnectDelayMs, mReconnectAttempts);
-
- if (DEBUG) {
- Log.d(TAG,
- "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
- }
-
- mCurrentReconnectCancelable = mMainExecutor.executeDelayed(mConnectRunnable,
- reconnectDelayMs);
-
- mReconnectAttempts++;
- }
-
- @Override
- protected void onBootCompleted() {
- if (mObserver.isPresent()) {
- mObserver.get().addCallback(mObserverCallback);
- }
- initiateConnectionAttempt();
- }
-
- private void connect() {
- if (DEBUG) {
- Log.d(TAG, "attempting to connect to communal source");
- }
-
- if (mCurrentConnection != null) {
- if (DEBUG) {
- Log.d(TAG, "canceling in-flight connection");
- }
- mCurrentConnection.disconnect();
- }
-
- mCurrentConnection = mConnector.get().connect(new CommunalSource.Connection.Callback() {
- private long mStartTime;
-
- @Override
- public void onSourceEstablished(Optional<CommunalSource> optionalSource) {
- mStartTime = mSystemClock.currentTimeMillis();
-
- if (optionalSource.isPresent()) {
- final CommunalSource source = optionalSource.get();
- mMonitor.setSource(source);
- } else {
- scheduleConnectionAttempt();
- }
- }
-
- @Override
- public void onDisconnected() {
- if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
- initiateConnectionAttempt();
- } else {
- scheduleConnectionAttempt();
- }
- }
- });
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java
deleted file mode 100644
index c72f5422b1f5..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.CallbackController;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-import javax.inject.Inject;
-
-/**
- * CommunalStateController enables publishing and listening to communal-related state changes.
- */
-@SysUISingleton
-public class CommunalStateController implements
- CallbackController<CommunalStateController.Callback> {
- private final ArrayList<Callback> mCallbacks = new ArrayList<>();
- private boolean mCommunalViewOccluded;
- private boolean mCommunalViewShowing;
-
- /**
- * Callback for communal events.
- */
- public interface Callback {
- /**
- * Called when the visibility of the communal view changes.
- */
- default void onCommunalViewShowingChanged() {
- }
-
- /**
- * Called when the occlusion of the communal view changes.
- */
- default void onCommunalViewOccludedChanged() {
- }
- }
-
- @VisibleForTesting
- @Inject
- public CommunalStateController() {
- }
-
- /**
- * Sets whether the communal view is showing.
- * @param communalViewShowing {@code true} if the view is showing, {@code false} otherwise.
- */
- public void setCommunalViewShowing(boolean communalViewShowing) {
- if (mCommunalViewShowing == communalViewShowing) {
- return;
- }
-
- mCommunalViewShowing = communalViewShowing;
-
- final ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
- for (Callback callback : callbacks) {
- callback.onCommunalViewShowingChanged();
- }
- }
-
- /**
- * Sets whether the communal view is occluded (but otherwise still showing).
- * @param communalViewOccluded {@code true} if the view is occluded, {@code false} otherwise.
- */
- public void setCommunalViewOccluded(boolean communalViewOccluded) {
- if (mCommunalViewOccluded == communalViewOccluded) {
- return;
- }
-
- mCommunalViewOccluded = communalViewOccluded;
-
- ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
- for (int i = 0; i < callbacks.size(); i++) {
- callbacks.get(i).onCommunalViewOccludedChanged();
- }
- }
-
- /**
- * Returns whether the communal view is showing.
- * @return {@code true} if the view is showing, {@code false} otherwise.
- */
- public boolean getCommunalViewShowing() {
- return mCommunalViewShowing;
- }
-
- /**
- * Returns whether the communal view is occluded.
- * @return {@code true} if the view is occluded, {@code false} otherwise.
- */
- public boolean getCommunalViewOccluded() {
- return mCommunalViewOccluded;
- }
-
- @Override
- public void addCallback(@NonNull Callback callback) {
- Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
- if (!mCallbacks.contains(callback)) {
- mCallbacks.add(callback);
- }
- }
-
- @Override
- public void removeCallback(@NonNull Callback callback) {
- Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
- mCallbacks.remove(callback);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java b/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java
deleted file mode 100644
index 3d25d126a291..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.PatternMatcher;
-import android.util.Log;
-
-import com.google.android.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * {@link PackageObserver} allows for monitoring the system for changes relating to a particular
- * package. This can be used by {@link CommunalSource} clients to detect when a related package
- * has changed and reloading is necessary.
- */
-public class PackageObserver implements CommunalSource.Observer {
- private static final String TAG = "PackageObserver";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) {
- Log.d(TAG, "package added receiver - onReceive");
- }
-
- final Iterator<WeakReference<Callback>> iter = mCallbacks.iterator();
- while (iter.hasNext()) {
- final Callback callback = iter.next().get();
- if (callback != null) {
- callback.onSourceChanged();
- } else {
- iter.remove();
- }
- }
- }
- };
-
- private final String mPackageName;
- private final Context mContext;
-
- public PackageObserver(Context context, String packageName) {
- mContext = context;
- mPackageName = packageName;
- }
-
- @Override
- public void addCallback(Callback callback) {
- if (DEBUG) {
- Log.d(TAG, "addCallback:" + callback);
- }
- mCallbacks.add(new WeakReference<>(callback));
-
- // Only register for listening to package additions on first callback.
- if (mCallbacks.size() > 1) {
- return;
- }
-
- final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
- filter.addDataScheme("package");
- filter.addDataSchemeSpecificPart(mPackageName, PatternMatcher.PATTERN_LITERAL);
- // Note that we directly register the receiver here as data schemes are not supported by
- // BroadcastDispatcher.
- mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
- }
-
- @Override
- public void removeCallback(Callback callback) {
- if (DEBUG) {
- Log.d(TAG, "removeCallback:" + callback);
- }
- final boolean removed = mCallbacks.removeIf(el -> el.get() == callback);
-
- if (removed && mCallbacks.isEmpty()) {
- mContext.unregisterReceiver(mReceiver);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java b/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java
deleted file mode 100644
index 25519d0f96c7..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.conditions;
-
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.annotation.MainThread;
-
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.settings.SecureSettings;
-
-import javax.inject.Inject;
-
-/**
- * Monitors the communal setting, and informs any listeners with updates.
- */
-public class CommunalSettingCondition extends Condition {
- private final SecureSettings mSecureSettings;
- private final ContentObserver mCommunalSettingContentObserver;
-
- @Inject
- public CommunalSettingCondition(@MainThread Handler mainHandler,
- SecureSettings secureSettings) {
- mSecureSettings = secureSettings;
-
- mCommunalSettingContentObserver = new ContentObserver(mainHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final boolean communalSettingEnabled = mSecureSettings.getIntForUser(
- Settings.Secure.COMMUNAL_MODE_ENABLED, 0, UserHandle.USER_SYSTEM) == 1;
- updateCondition(communalSettingEnabled);
- }
- };
- }
-
- @Override
- protected void start() {
- mSecureSettings.registerContentObserverForUser(Settings.Secure.COMMUNAL_MODE_ENABLED,
- false /*notifyForDescendants*/, mCommunalSettingContentObserver,
- UserHandle.USER_SYSTEM);
-
- // Fetches setting immediately.
- mCommunalSettingContentObserver.onChange(false);
- }
-
- @Override
- protected void stop() {
- mSecureSettings.unregisterContentObserver(mCommunalSettingContentObserver);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
deleted file mode 100644
index 814b251d08ab..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.dagger;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.PackageObserver;
-import com.android.systemui.communal.conditions.CommunalSettingCondition;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.condition.Monitor;
-import com.android.systemui.util.condition.dagger.MonitorComponent;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.inject.Named;
-import javax.inject.Provider;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.StringKey;
-
-/**
- * Dagger Module providing Communal-related functionality.
- */
-@Module(subcomponents = {
- CommunalViewComponent.class,
-})
-public interface CommunalModule {
- String COMMUNAL_CONDITIONS = "communal_conditions";
-
- /** */
- @Provides
- static Optional<CommunalSource.Observer> provideCommunalSourcePackageObserver(
- Context context, @Main Resources resources) {
- final String componentName = resources.getString(R.string.config_communalSourceComponent);
-
- if (TextUtils.isEmpty(componentName)) {
- return Optional.empty();
- }
-
- return Optional.of(new PackageObserver(context,
- ComponentName.unflattenFromString(componentName).getPackageName()));
- }
-
- /**
- * Provides a set of conditions that need to be fulfilled in order for Communal Mode to display.
- */
- @Provides
- @ElementsIntoSet
- @Named(COMMUNAL_CONDITIONS)
- static Set<Condition> provideCommunalConditions(
- CommunalSettingCondition communalSettingCondition) {
- return new HashSet<>(Collections.singletonList(communalSettingCondition));
- }
-
- /**
- * TODO(b/205638389): Remove when there is a base implementation of
- * {@link CommunalSource.Connector}. Currently a place holder to allow a map to be present.
- */
- @Provides
- @IntoMap
- @Nullable
- @StringKey("empty")
- static CommunalSource.Connector provideEmptyCommunalSourceConnector() {
- return null;
- }
-
- /** */
- @Provides
- static Optional<CommunalSource.Connector> provideCommunalSourceConnector(
- @Main Resources resources,
- Map<Class<?>, Provider<CommunalSource.Connector>> connectorCreators) {
- final String className = resources.getString(R.string.config_communalSourceConnector);
-
- if (TextUtils.isEmpty(className)) {
- return Optional.empty();
- }
-
- try {
- Class<?> clazz = Class.forName(className);
- Provider<CommunalSource.Connector> provider = connectorCreators.get(clazz);
- return provider != null ? Optional.of(provider.get()) : Optional.empty();
- } catch (ClassNotFoundException e) {
- return Optional.empty();
- }
- }
-
- /** */
- @Provides
- @Named(COMMUNAL_CONDITIONS)
- static Monitor provideCommunalSourceMonitor(
- @Named(COMMUNAL_CONDITIONS) Set<Condition> communalConditions,
- MonitorComponent.Factory factory) {
- final MonitorComponent component = factory.create(communalConditions, new HashSet<>());
- return component.getMonitor();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java
deleted file mode 100644
index 3a80a03aecb2..000000000000
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.dagger;
-
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-
-import dagger.BindsInstance;
-import dagger.Subcomponent;
-
-/**
- * Subcomponent for working with {@link CommunalHostView}.
- */
-@Subcomponent
-public interface CommunalViewComponent {
- /** Simple factory for {@link CommunalViewComponent}. */
- @Subcomponent.Factory
- interface Factory {
- CommunalViewComponent build(@BindsInstance CommunalHostView view);
- }
-
- /** Builds a {@link CommunalHostViewController}. */
- CommunalHostViewController getCommunalHostViewController();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 18f85196aa0b..620feec8fbb8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -23,10 +23,14 @@ import android.util.DisplayMetrics;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.dagger.qualifiers.TestHarness;
+import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.PluginsModule;
import com.android.systemui.unfold.UnfoldTransitionModule;
import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
import javax.inject.Singleton;
import dagger.Module;
@@ -75,4 +79,16 @@ public class GlobalModule {
static boolean provideIsTestHarness() {
return ActivityManager.isRunningInUserTestHarness();
}
+
+ /**
+ * Provide an Executor specifically for running UI operations on a separate thread.
+ *
+ * Keep submitted runnables short and to the point, just as with any other UI code.
+ */
+ @Provides
+ @Singleton
+ @UiBackground
+ public static Executor provideUiBackgroundExecutor() {
+ return Executors.newSingleThreadExecutor();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
index a3a45fe7ae40..4f55ba496b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
@@ -27,10 +27,7 @@ import dagger.Component;
* Root component for Dagger injection.
*/
@Singleton
-@Component(modules = {
- GlobalModule.class,
- SysUISubcomponentModule.class,
- WMModule.class})
+@Component(modules = {GlobalModule.class})
public interface GlobalRootComponent {
/**
@@ -45,12 +42,12 @@ public interface GlobalRootComponent {
}
/**
- * Builder for a WMComponent.
+ * Builder for a {@link WMComponent}, which makes it a subcomponent of this class.
*/
WMComponent.Builder getWMComponentBuilder();
/**
- * Builder for a SysUIComponent.
+ * Builder for a {@link SysUIComponent}, which makes it a subcomponent of this class.
*/
SysUIComponent.Builder getSysUIComponent();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 27993010c917..166c2654cbaa 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -32,7 +32,6 @@ import com.android.systemui.assist.AssistModule;
import com.android.systemui.biometrics.UdfpsHbmProvider;
import com.android.systemui.biometrics.dagger.BiometricsModule;
import com.android.systemui.classifier.FalsingModule;
-import com.android.systemui.communal.dagger.CommunalModule;
import com.android.systemui.controls.dagger.ControlsModule;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.demomode.dagger.DemoModeModule;
@@ -49,6 +48,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.Recents;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
import com.android.systemui.settings.dagger.SettingsModule;
+import com.android.systemui.smartspace.dagger.SmartspaceModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -66,8 +66,8 @@ import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
-import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -106,7 +106,6 @@ import dagger.Provides;
AssistModule.class,
BiometricsModule.class,
ClockModule.class,
- CommunalModule.class,
DreamModule.class,
ControlsModule.class,
DemoModeModule.class,
@@ -121,6 +120,7 @@ import dagger.Provides;
SettingsModule.class,
SettingsUtilModule.class,
SmartRepliesInflationModule.class,
+ SmartspaceModule.class,
StatusBarPolicyModule.class,
StatusBarWindowModule.class,
SysUIConcurrencyModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index ebc766635733..dfbb0c7c1624 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -65,6 +65,9 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
// A reference to the {@link Window} used to hold the dream overlay.
private Window mWindow;
+ // True if the service has been destroyed.
+ private boolean mDestroyed;
+
private final Complication.Host mHost = new Complication.Host() {
@Override
public void requestExitDream() {
@@ -134,6 +137,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mPreviewComplication.setDreamLabel(null);
mStateController.removeComplication(mPreviewComplication);
mStateController.setPreviewMode(false);
+ mDestroyed = true;
super.onDestroy();
}
@@ -141,6 +145,11 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
setCurrentState(Lifecycle.State.STARTED);
mExecutor.execute(() -> {
+ if (mDestroyed) {
+ // The task could still be executed after the service has been destroyed. Bail if
+ // that is the case.
+ return;
+ }
mStateController.setShouldShowComplications(shouldShowComplications());
mStateController.setPreviewMode(isPreviewMode());
if (isPreviewMode()) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index a5dcd39264df..a83e006dfa2f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
@@ -17,6 +17,7 @@
package com.android.systemui.dreams;
import android.content.Context;
+import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -25,7 +26,10 @@ import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.complication.Complication;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
import com.android.systemui.dreams.complication.ComplicationViewModel;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
+
+import java.util.List;
import javax.inject.Inject;
@@ -39,10 +43,22 @@ public class SmartSpaceComplication implements Complication {
* SystemUI.
*/
public static class Registrant extends CoreStartable {
- private final LockscreenSmartspaceController mSmartSpaceController;
+ private final DreamsSmartspaceController mSmartSpaceController;
private final DreamOverlayStateController mDreamOverlayStateController;
private final SmartSpaceComplication mComplication;
+ private final BcSmartspaceDataPlugin.SmartspaceTargetListener mSmartspaceListener =
+ new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
+ @Override
+ public void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets) {
+ if (!targets.isEmpty()) {
+ mDreamOverlayStateController.addComplication(mComplication);
+ } else {
+ mDreamOverlayStateController.removeComplication(mComplication);
+ }
+ }
+ };
+
/**
* Default constructor for {@link SmartSpaceComplication}.
*/
@@ -50,7 +66,7 @@ public class SmartSpaceComplication implements Complication {
public Registrant(Context context,
DreamOverlayStateController dreamOverlayStateController,
SmartSpaceComplication smartSpaceComplication,
- LockscreenSmartspaceController smartSpaceController) {
+ DreamsSmartspaceController smartSpaceController) {
super(context);
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = smartSpaceComplication;
@@ -59,32 +75,27 @@ public class SmartSpaceComplication implements Complication {
@Override
public void start() {
- addOrRemoveOverlay();
mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
@Override
public void onStateChanged() {
- addOrRemoveOverlay();
+ if (mDreamOverlayStateController.isOverlayActive()) {
+ mSmartSpaceController.addListener(mSmartspaceListener);
+ } else {
+ mSmartSpaceController.removeListener(mSmartspaceListener);
+ }
}
});
}
-
- private void addOrRemoveOverlay() {
- if (mDreamOverlayStateController.isPreviewMode()) {
- mDreamOverlayStateController.removeComplication(mComplication);
- } else if (mSmartSpaceController.isEnabled()) {
- mDreamOverlayStateController.addComplication(mComplication);
- }
- }
}
private static class SmartSpaceComplicationViewHolder implements ViewHolder {
private static final int SMARTSPACE_COMPLICATION_WEIGHT = 10;
- private final LockscreenSmartspaceController mSmartSpaceController;
+ private final DreamsSmartspaceController mSmartSpaceController;
private final Context mContext;
protected SmartSpaceComplicationViewHolder(
Context context,
- LockscreenSmartspaceController smartSpaceController) {
+ DreamsSmartspaceController smartSpaceController) {
mSmartSpaceController = smartSpaceController;
mContext = context;
}
@@ -109,12 +120,12 @@ public class SmartSpaceComplication implements Complication {
}
}
- private final LockscreenSmartspaceController mSmartSpaceController;
+ private final DreamsSmartspaceController mSmartSpaceController;
private final Context mContext;
@Inject
public SmartSpaceComplication(Context context,
- LockscreenSmartspaceController smartSpaceController) {
+ DreamsSmartspaceController smartSpaceController) {
mContext = context;
mSmartSpaceController = smartSpaceController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
index 62b319bd9e97..4e528bbe9386 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
@@ -21,6 +21,7 @@ import static com.android.systemui.dreams.complication.dagger.ComplicationModule
import android.graphics.Rect;
import android.graphics.Region;
+import android.util.Log;
import android.view.View;
import androidx.constraintlayout.widget.ConstraintLayout;
@@ -42,6 +43,8 @@ import javax.inject.Named;
* a {@link ComplicationLayoutEngine}.
*/
public class ComplicationHostViewController extends ViewController<ConstraintLayout> {
+ public static final String TAG = "ComplicationHostViewController";
+
private final ComplicationLayoutEngine mLayoutEngine;
private final LifecycleOwner mLifecycleOwner;
private final ComplicationCollectionViewModel mComplicationCollectionViewModel;
@@ -113,6 +116,12 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
final Complication.ViewHolder viewHolder = complication.getComplication()
.createView(complication);
mComplications.put(id, viewHolder);
+ if (viewHolder.getView().getParent() != null) {
+ Log.e(TAG, "View for complication "
+ + complication.getComplication().getClass()
+ + " already has a parent. Make sure not to reuse complication "
+ + "views!");
+ }
mLayoutEngine.addComplication(id, viewHolder.getView(),
viewHolder.getLayoutParams(), viewHolder.getCategory());
});
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index de5b4bb9e520..c7b02cd00e96 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -26,7 +26,7 @@ import dagger.Module;
import dagger.Provides;
/**
- * Dagger Module providing Communal-related functionality.
+ * Dagger Module providing Dream-related functionality.
*/
@Module(includes = {
RegisteredComplicationsModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
new file mode 100644
index 000000000000..4e228a14fc88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
@@ -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.systemui.dreams.smartspace
+
+import android.app.smartspace.SmartspaceConfig
+import android.app.smartspace.SmartspaceManager
+import android.app.smartspace.SmartspaceSession
+import android.content.Context
+import android.graphics.Color
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_DATA_PLUGIN
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_PRECONDITION
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_TARGET_FILTER
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
+import com.android.systemui.util.concurrency.Execution
+import java.lang.RuntimeException
+import java.util.Optional
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * Controller for managing the smartspace view on the dream
+ */
+@SysUISingleton
+class DreamsSmartspaceController @Inject constructor(
+ private val context: Context,
+ private val smartspaceManager: SmartspaceManager,
+ private val execution: Execution,
+ @Main private val uiExecutor: Executor,
+ private val smartspaceViewComponentFactory: SmartspaceViewComponent.Factory,
+ @Named(DREAM_SMARTSPACE_PRECONDITION) private val precondition: SmartspacePrecondition,
+ @Named(DREAM_SMARTSPACE_TARGET_FILTER)
+ private val optionalTargetFilter: Optional<SmartspaceTargetFilter>,
+ @Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>
+) {
+ companion object {
+ private const val TAG = "DreamsSmartspaceCtrlr"
+ }
+
+ private var session: SmartspaceSession? = null
+ private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null)
+ private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null)
+
+ // A shadow copy of listeners is maintained to track whether the session should remain open.
+ private var listeners = mutableSetOf<BcSmartspaceDataPlugin.SmartspaceTargetListener>()
+
+ // Smartspace can be used on multiple displays, such as when the user casts their screen
+ private var smartspaceViews = mutableSetOf<SmartspaceView>()
+
+ var preconditionListener = object : SmartspacePrecondition.Listener {
+ override fun onCriteriaChanged() {
+ reloadSmartspace()
+ }
+ }
+
+ init {
+ precondition.addListener(preconditionListener)
+ }
+
+ var filterListener = object : SmartspaceTargetFilter.Listener {
+ override fun onCriteriaChanged() {
+ reloadSmartspace()
+ }
+ }
+
+ init {
+ targetFilter?.addListener(filterListener)
+ }
+
+ var stateChangeListener = object : View.OnAttachStateChangeListener {
+ override fun onViewAttachedToWindow(v: View) {
+ val view = v as SmartspaceView
+ // Until there is dream color matching
+ view.setPrimaryTextColor(Color.WHITE)
+ smartspaceViews.add(view)
+ connectSession()
+ }
+
+ override fun onViewDetachedFromWindow(v: View) {
+ smartspaceViews.remove(v as SmartspaceView)
+
+ if (smartspaceViews.isEmpty()) {
+ disconnect()
+ }
+ }
+ }
+
+ private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
+ execution.assertIsMainThread()
+
+ val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true }
+ plugin?.onTargetsAvailable(filteredTargets)
+ }
+
+ /**
+ * Constructs the smartspace view and connects it to the smartspace service.
+ */
+ fun buildAndConnectView(parent: ViewGroup): View? {
+ execution.assertIsMainThread()
+
+ if (!precondition.conditionsMet()) {
+ throw RuntimeException("Cannot build view when not enabled")
+ }
+
+ val view = buildView(parent)
+ connectSession()
+
+ return view
+ }
+
+ private fun buildView(parent: ViewGroup): View? {
+ return if (plugin != null) {
+ var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener)
+ .getView()
+
+ if (view is View) {
+ return view
+ }
+
+ return null
+ } else {
+ null
+ }
+ }
+
+ private fun hasActiveSessionListeners(): Boolean {
+ return smartspaceViews.isNotEmpty() || listeners.isNotEmpty()
+ }
+
+ private fun connectSession() {
+ if (plugin == null || session != null || !hasActiveSessionListeners()) {
+ return
+ }
+
+ if (!precondition.conditionsMet()) {
+ return
+ }
+
+ // TODO(b/217559844): Replace with "dream" session when available.
+ val newSession = smartspaceManager.createSmartspaceSession(
+ SmartspaceConfig.Builder(context, "lockscreen").build())
+ Log.d(TAG, "Starting smartspace session for dream")
+ newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
+ this.session = newSession
+
+ plugin.registerSmartspaceEventNotifier {
+ e -> session?.notifySmartspaceEvent(e)
+ }
+
+ reloadSmartspace()
+ }
+
+ /**
+ * Disconnects the smartspace view from the smartspace service and cleans up any resources.
+ */
+ private fun disconnect() {
+ if (hasActiveSessionListeners()) return
+
+ execution.assertIsMainThread()
+
+ if (session == null) {
+ return
+ }
+
+ session?.let {
+ it.removeOnTargetsAvailableListener(sessionListener)
+ it.close()
+ }
+
+ session = null
+
+ plugin?.registerSmartspaceEventNotifier(null)
+ plugin?.onTargetsAvailable(emptyList())
+ Log.d(TAG, "Ending smartspace session for dream")
+ }
+
+ fun addListener(listener: SmartspaceTargetListener) {
+ execution.assertIsMainThread()
+ plugin?.registerListener(listener)
+ listeners.add(listener)
+
+ connectSession()
+ }
+
+ fun removeListener(listener: SmartspaceTargetListener) {
+ execution.assertIsMainThread()
+ plugin?.unregisterListener(listener)
+ listeners.remove(listener)
+ disconnect()
+ }
+
+ private fun reloadSmartspace() {
+ session?.requestSmartspaceUpdate()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 7a278f786a67..af553c744311 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -624,7 +624,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
addIfShouldShowAction(tempActions, new LogoutAction());
}
} else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
- addIfShouldShowAction(tempActions, new EmergencyDialerAction());
+ if (shouldDisplayEmergency()) {
+ addIfShouldShowAction(tempActions, new EmergencyDialerAction());
+ }
} else {
Log.e(TAG, "Invalid global action key " + actionKey);
}
@@ -704,6 +706,12 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
}
@VisibleForTesting
+ boolean shouldDisplayEmergency() {
+ // Emergency calling requires a telephony radio.
+ return mHasTelephony;
+ }
+
+ @VisibleForTesting
boolean shouldDisplayBugReport(UserInfo currentUser) {
return mGlobalSettings.getInt(Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0
&& (currentUser == null || currentUser.isPrimary());
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 04a324b87382..355c69f9a48d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -211,10 +211,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
ColorFilter buttonColorFilter = new PorterDuffColorFilter(
mAdapter.getController().getColorButtonBackground(),
PorterDuff.Mode.SRC_IN);
- ColorFilter onlineButtonColorFilter = new PorterDuffColorFilter(
- mAdapter.getController().getColorInactiveItem(), PorterDuff.Mode.SRC_IN);
mDoneButton.getBackground().setColorFilter(buttonColorFilter);
- mStopButton.getBackground().setColorFilter(onlineButtonColorFilter);
+ mStopButton.getBackground().setColorFilter(buttonColorFilter);
}
mHeaderIcon.setVisibility(View.VISIBLE);
mHeaderIcon.setImageIcon(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index f16ca7dd7361..0c202e09b62e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -30,12 +30,16 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.media.INearbyMediaDevicesUpdateCallback;
import android.media.MediaMetadata;
import android.media.MediaRoute2Info;
+import android.media.NearbyDevice;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -61,6 +65,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.monet.ColorScheme;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -70,6 +75,9 @@ import com.android.systemui.statusbar.phone.ShadeController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject;
@@ -77,7 +85,8 @@ import javax.inject.Inject;
/**
* Controller for media output dialog
*/
-public class MediaOutputController implements LocalMediaManager.DeviceCallback {
+public class MediaOutputController implements LocalMediaManager.DeviceCallback,
+ INearbyMediaDevicesUpdateCallback {
private static final String TAG = "MediaOutputController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -95,6 +104,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
private final CommonNotifCollection mNotifCollection;
@VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
+ private final NearbyMediaDevicesManager mNearbyMediaDevicesManager;
+ private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>();
private MediaController mMediaController;
@VisibleForTesting
@@ -116,7 +127,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
lbm, ShadeController shadeController, ActivityStarter starter,
CommonNotifCollection notifCollection, UiEventLogger uiEventLogger,
- DialogLaunchAnimator dialogLaunchAnimator) {
+ DialogLaunchAnimator dialogLaunchAnimator,
+ Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) {
mContext = context;
mPackageName = packageName;
mMediaSessionManager = mediaSessionManager;
@@ -130,6 +142,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mUiEventLogger = uiEventLogger;
mDialogLaunchAnimator = dialogLaunchAnimator;
+ mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
R.color.media_dialog_active_item_main_content);
mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
@@ -144,6 +157,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
void start(@NonNull Callback cb) {
mMediaDevices.clear();
+ mNearbyDeviceInfoMap.clear();
+ if (mNearbyMediaDevicesManager != null) {
+ mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this);
+ }
if (!TextUtils.isEmpty(mPackageName)) {
for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
@@ -187,6 +204,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager.stopScan();
}
mMediaDevices.clear();
+ if (mNearbyMediaDevicesManager != null) {
+ mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
+ }
+ mNearbyDeviceInfoMap.clear();
}
@Override
@@ -417,6 +438,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
}
mMediaDevices.clear();
mMediaDevices.addAll(targetMediaDevices);
+ attachRangeInfo();
+ }
+
+ private void attachRangeInfo() {
+ for (MediaDevice mediaDevice : mMediaDevices) {
+ if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
+ mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId()));
+ }
+ }
}
List<MediaDevice> getGroupMediaDevices() {
@@ -604,7 +634,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
// We show the output group dialog from the output dialog.
MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController,
- mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+ mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
+
MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar,
controller);
mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
@@ -629,6 +661,20 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
|| mLocalMediaManager.isMediaSessionAvailableForVolumeControl();
}
+ @Override
+ public void onDevicesUpdated(List<NearbyDevice> nearbyDevices) throws RemoteException {
+ mNearbyDeviceInfoMap.clear();
+ for (NearbyDevice nearbyDevice : nearbyDevices) {
+ mNearbyDeviceInfoMap.put(nearbyDevice.getMediaRoute2Id(), nearbyDevice.getRangeZone());
+ }
+ mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+
private final MediaController.Callback mCb = new MediaController.Callback() {
@Override
public void onMetadataChanged(MediaMetadata metadata) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
index 9e252ea1eddc..a7e54801bf47 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
@@ -22,9 +22,11 @@ import android.view.View
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.phone.ShadeController
+import java.util.Optional
import javax.inject.Inject
/**
@@ -38,7 +40,8 @@ class MediaOutputDialogFactory @Inject constructor(
private val starter: ActivityStarter,
private val notifCollection: CommonNotifCollection,
private val uiEventLogger: UiEventLogger,
- private val dialogLaunchAnimator: DialogLaunchAnimator
+ private val dialogLaunchAnimator: DialogLaunchAnimator,
+ private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>
) {
companion object {
var mediaOutputDialog: MediaOutputDialog? = null
@@ -50,8 +53,8 @@ class MediaOutputDialogFactory @Inject constructor(
mediaOutputDialog?.dismiss()
val controller = MediaOutputController(context, packageName, aboveStatusBar,
- mediaSessionManager, lbm, shadeController, starter, notifCollection,
- uiEventLogger, dialogLaunchAnimator)
+ mediaSessionManager, lbm, shadeController, starter, notifCollection,
+ uiEventLogger, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional)
val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger)
mediaOutputDialog = dialog
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
index 9dd8222ff6a1..3961f079748b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media.taptotransfer
+import android.annotation.SuppressLint
import android.app.StatusBarManager
import android.content.Context
import android.media.MediaRoute2Info
@@ -23,16 +24,12 @@ import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToEndCast
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToStartCast
-import com.android.systemui.media.taptotransfer.sender.TransferFailed
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceSucceeded
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverSucceeded
+import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
+import java.lang.IllegalArgumentException
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -46,28 +43,6 @@ class MediaTttCommandLineHelper @Inject constructor(
private val context: Context,
@Main private val mainExecutor: Executor
) {
- /**
- * A map from a display state string typed in the command line to the display int it represents.
- */
- private val stateStringToStateInt: Map<String, Int> = mapOf(
- AlmostCloseToStartCast::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
- AlmostCloseToEndCast::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
- TransferToReceiverTriggered::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
- TransferToThisDeviceTriggered::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
- TransferToReceiverSucceeded::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
- TransferToThisDeviceSucceeded::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
- TransferFailed::class.simpleName!!
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
- FAR_FROM_RECEIVER_STATE
- to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER
- )
-
init {
commandRegistry.registerCommand(SENDER_COMMAND) { SenderCommand() }
commandRegistry.registerCommand(RECEIVER_COMMAND) { ReceiverCommand() }
@@ -76,21 +51,23 @@ class MediaTttCommandLineHelper @Inject constructor(
/** All commands for the sender device. */
inner class SenderCommand : Command {
override fun execute(pw: PrintWriter, args: List<String>) {
- val routeInfo = MediaRoute2Info.Builder("id", args[0])
- .addFeature("feature")
- .setPackageName(TEST_PACKAGE_NAME)
- .build()
-
val commandName = args[1]
@StatusBarManager.MediaTransferSenderState
- val displayState = stateStringToStateInt[commandName]
- if (displayState == null) {
+ val displayState: Int?
+ try {
+ displayState = ChipStateSender.getSenderStateIdFromName(commandName)
+ } catch (ex: IllegalArgumentException) {
pw.println("Invalid command name $commandName")
return
}
+ @SuppressLint("WrongConstant") // sysui allowed to call STATUS_BAR_SERVICE
val statusBarManager = context.getSystemService(Context.STATUS_BAR_SERVICE)
as StatusBarManager
+ val routeInfo = MediaRoute2Info.Builder("id", args[0])
+ .addFeature("feature")
+ .setPackageName(TEST_PACKAGE_NAME)
+ .build()
statusBarManager.updateMediaTapToTransferSenderDisplay(
displayState,
routeInfo,
@@ -136,6 +113,17 @@ class MediaTttCommandLineHelper @Inject constructor(
/** All commands for the receiver device. */
inner class ReceiverCommand : Command {
override fun execute(pw: PrintWriter, args: List<String>) {
+ val commandName = args[0]
+ @StatusBarManager.MediaTransferReceiverState
+ val displayState: Int?
+ try {
+ displayState = ChipStateReceiver.getReceiverStateIdFromName(commandName)
+ } catch (ex: IllegalArgumentException) {
+ pw.println("Invalid command name $commandName")
+ return
+ }
+
+ @SuppressLint("WrongConstant") // sysui is allowed to call STATUS_BAR_SERVICE
val statusBarManager = context.getSystemService(Context.STATUS_BAR_SERVICE)
as StatusBarManager
val routeInfo = MediaRoute2Info.Builder("id", "Test Name")
@@ -143,24 +131,12 @@ class MediaTttCommandLineHelper @Inject constructor(
.setPackageName(TEST_PACKAGE_NAME)
.build()
- when(val commandName = args[0]) {
- CLOSE_TO_SENDER_STATE ->
- statusBarManager.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
- routeInfo,
- null,
- null
- )
- FAR_FROM_SENDER_STATE ->
- statusBarManager.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
- routeInfo,
- null,
- null
- )
- else ->
- pw.println("Invalid command name $commandName")
- }
+ statusBarManager.updateMediaTapToTransferReceiverDisplay(
+ displayState,
+ routeInfo,
+ null,
+ null
+ )
}
override fun help(pw: PrintWriter) {
@@ -173,11 +149,5 @@ class MediaTttCommandLineHelper @Inject constructor(
const val SENDER_COMMAND = "media-ttt-chip-sender"
@VisibleForTesting
const val RECEIVER_COMMAND = "media-ttt-chip-receiver"
-@VisibleForTesting
-const val FAR_FROM_RECEIVER_STATE = "FarFromReceiver"
-@VisibleForTesting
-const val CLOSE_TO_SENDER_STATE = "CloseToSender"
-@VisibleForTesting
-const val FAR_FROM_SENDER_STATE = "FarFromSender"
private const val CLI_TAG = "MediaTransferCli"
private const val TEST_PACKAGE_NAME = "com.android.systemui"
diff --git a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
index bf5e3ccb4ac7..3cc99a8ef77e 100644
--- a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 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,15 +14,17 @@
* limitations under the License.
*/
-.headers on
-.mode quote
+package com.android.systemui.media.taptotransfer.common
-SELECT * FROM blocked_iowait_for_app_launches;
-
-/*
-Output as CSV example:
-
-'blocked_iowait_duration_ms','process_name','launching_duration_ms','launching_started_timestamp_ms','launching_finished_timestamp_ms'
-125.33199995596078224,'com.android.settings',1022.4840000009862706,17149896.822000000626,17150919.305999998003
+/**
+ * A superclass chip state that will be subclassed by the sender chip and receiver chip.
+ */
+interface ChipInfoCommon {
+ /**
+ * Returns the amount of time the given chip state should display on the screen before it times
+ * out and disappears.
+ */
+ fun getTimeoutMs(): Long
+}
-*/
+const val DEFAULT_TIMEOUT_MILLIS = 3000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
index 9c4b39d9cb77..71cacac7f4df 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -19,14 +19,18 @@ package com.android.systemui.media.taptotransfer.common
import android.annotation.LayoutRes
import android.annotation.SuppressLint
import android.content.Context
+import android.content.pm.PackageManager
import android.graphics.PixelFormat
+import android.graphics.drawable.Drawable
+import android.os.PowerManager
+import android.os.SystemClock
+import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
-import androidx.annotation.VisibleForTesting
import com.android.internal.widget.CachingIconView
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Main
@@ -40,14 +44,18 @@ import com.android.systemui.util.view.ViewUtil
*
* Subclasses need to override and implement [updateChipView], which is where they can control what
* gets displayed to the user.
+ *
+ * The generic type T is expected to contain all the information necessary for the subclasses to
+ * display the chip in a certain state, since they receive <T> in [updateChipView].
*/
-abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
+abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
internal val context: Context,
internal val logger: MediaTttLogger,
private val windowManager: WindowManager,
private val viewUtil: ViewUtil,
@Main private val mainExecutor: DelayableExecutor,
private val tapGestureDetector: TapGestureDetector,
+ private val powerManager: PowerManager,
@LayoutRes private val chipLayoutRes: Int
) {
/** The window layout parameters we'll use when attaching the view to a window. */
@@ -64,10 +72,10 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
}
/** The chip view currently being displayed. Null if the chip is not being displayed. */
- var chipView: ViewGroup? = null
+ private var chipView: ViewGroup? = null
/** A [Runnable] that, when run, will cancel the pending timeout of the chip. */
- var cancelChipViewTimeout: Runnable? = null
+ private var cancelChipViewTimeout: Runnable? = null
/**
* Displays the chip with the current state.
@@ -75,7 +83,7 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
* This method handles inflating and attaching the view, then delegates to [updateChipView] to
* display the correct information in the chip.
*/
- fun displayChip(chipState: T) {
+ fun displayChip(chipInfo: T) {
val oldChipView = chipView
if (chipView == null) {
chipView = LayoutInflater
@@ -84,19 +92,25 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
}
val currentChipView = chipView!!
- updateChipView(chipState, currentChipView)
+ updateChipView(chipInfo, currentChipView)
// Add view if necessary
if (oldChipView == null) {
tapGestureDetector.addOnGestureDetectedCallback(TAG, this::onScreenTapped)
windowManager.addView(chipView, windowLayoutParams)
+ // Wake the screen so the user will see the chip
+ powerManager.wakeUp(
+ SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION,
+ "com.android.systemui:media_tap_to_transfer_activated"
+ )
}
// Cancel and re-set the chip timeout each time we get a new state.
cancelChipViewTimeout?.run()
cancelChipViewTimeout = mainExecutor.executeDelayed(
{ removeChip(MediaTttRemovalReason.REASON_TIMEOUT) },
- chipState.getTimeoutMs()
+ chipInfo.getTimeoutMs()
)
}
@@ -117,20 +131,28 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
}
/**
- * A method implemented by subclasses to update [currentChipView] based on [chipState].
+ * A method implemented by subclasses to update [currentChipView] based on [chipInfo].
*/
- abstract fun updateChipView(chipState: T, currentChipView: ViewGroup)
+ abstract fun updateChipView(chipInfo: T, currentChipView: ViewGroup)
/**
* An internal method to set the icon on the view.
*
* This is in the common superclass since both the sender and the receiver show an icon.
+ *
+ * @param appPackageName the package name of the app playing the media. Will be used to fetch
+ * the app icon and app name if overrides aren't provided.
*/
- internal fun setIcon(chipState: T, currentChipView: ViewGroup) {
+ internal fun setIcon(
+ currentChipView: ViewGroup,
+ appPackageName: String?,
+ appIconDrawableOverride: Drawable? = null,
+ appNameOverride: CharSequence? = null,
+ ) {
val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
- appIconView.contentDescription = chipState.getAppName(context)
+ appIconView.contentDescription = appNameOverride ?: getAppName(appPackageName)
- val appIcon = chipState.getAppIcon(context)
+ val appIcon = appIconDrawableOverride ?: getAppIcon(appPackageName)
val visibility = if (appIcon != null) {
View.VISIBLE
} else {
@@ -140,6 +162,30 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
appIconView.visibility = visibility
}
+ /** Returns the icon of the app playing the media or null if we can't find it. */
+ private fun getAppIcon(appPackageName: String?): Drawable? {
+ appPackageName ?: return null
+ return try {
+ context.packageManager.getApplicationIcon(appPackageName)
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Cannot find icon for package $appPackageName", e)
+ null
+ }
+ }
+
+ /** Returns the name of the app playing the media or null if we can't find it. */
+ private fun getAppName(appPackageName: String?): String? {
+ appPackageName ?: return null
+ return try {
+ context.packageManager.getApplicationInfo(
+ appPackageName, PackageManager.ApplicationInfoFlags.of(0)
+ ).loadLabel(context.packageManager).toString()
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Cannot find name for package $appPackageName", e)
+ null
+ }
+ }
+
private fun onScreenTapped(e: MotionEvent) {
val view = chipView ?: return
// If the tap is within the chip bounds, we shouldn't hide the chip (in case users think the
@@ -159,4 +205,3 @@ object MediaTttRemovalReason {
const val REASON_TIMEOUT = "TIMEOUT"
const val REASON_SCREEN_TAP = "SCREEN_TAP"
}
-
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
deleted file mode 100644
index 6f6018170f98..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.taptotransfer.common
-
-import android.content.Context
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import android.util.Log
-
-/**
- * A superclass chip state that will be subclassed by the sender chip and receiver chip.
- *
- * @property appPackageName the package name of the app playing the media. Will be used to fetch the
- * app icon and app name.
- */
-open class MediaTttChipState(
- internal val appPackageName: String?,
-) {
- open fun getAppIcon(context: Context): Drawable? {
- appPackageName ?: return null
- return try {
- context.packageManager.getApplicationIcon(appPackageName)
- } catch (e: PackageManager.NameNotFoundException) {
- Log.w(TAG, "Cannot find icon for package $appPackageName", e)
- null
- }
- }
-
- /** Returns the name of the app playing the media or null if we can't find it. */
- open fun getAppName(context: Context): String? {
- appPackageName ?: return null
- return try {
- context.packageManager.getApplicationInfo(
- appPackageName, PackageManager.ApplicationInfoFlags.of(0)
- ).loadLabel(context.packageManager).toString()
- } catch (e: PackageManager.NameNotFoundException) {
- Log.w(TAG, "Cannot find name for package $appPackageName", e)
- null
- }
- }
-
- /**
- * Returns the amount of time this chip should display on the screen before it times out and
- * disappears. [MediaTttChipControllerCommon] will ensure that the timeout resets each time we
- * receive a new state.
- */
- open fun getTimeoutMs(): Long = DEFAULT_TIMEOUT_MILLIS
-}
-
-private const val DEFAULT_TIMEOUT_MILLIS = 3000L
-private val TAG = MediaTttChipState::class.simpleName!!
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
index 6a4b62a8c1ae..a0e803f6bb8d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
@@ -16,35 +16,43 @@
package com.android.systemui.media.taptotransfer.receiver
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.android.systemui.media.taptotransfer.common.MediaTttChipState
+import android.app.StatusBarManager
+import com.android.internal.logging.UiEventLogger
/**
* A class that stores all the information necessary to display the media tap-to-transfer chip on
* the receiver device.
- *
- * @property appIconDrawable a drawable representing the icon of the app playing the media. If
- * present, this will be used in [this.getAppIcon] instead of [appPackageName].
- * @property appName a name for the app playing the media. If present, this will be used in
- * [this.getAppName] instead of [appPackageName].
*/
-class ChipStateReceiver(
- appPackageName: String?,
- private val appIconDrawable: Drawable?,
- private val appName: CharSequence?
-) : MediaTttChipState(appPackageName) {
- override fun getAppIcon(context: Context): Drawable? {
- if (appIconDrawable != null) {
- return appIconDrawable
- }
- return super.getAppIcon(context)
- }
+enum class ChipStateReceiver(
+ @StatusBarManager.MediaTransferSenderState val stateInt: Int,
+ val uiEvent: UiEventLogger.UiEventEnum,
+) {
+ CLOSE_TO_SENDER(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER,
+ ),
+ FAR_FROM_SENDER(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER,
+ );
+
+ companion object {
+ /**
+ * Returns the receiver state enum associated with the given [displayState] from
+ * [StatusBarManager].
+ */
+ fun getReceiverStateFromId(
+ @StatusBarManager.MediaTransferReceiverState displayState: Int
+ ) : ChipStateReceiver = values().first { it.stateInt == displayState }
+
- override fun getAppName(context: Context): String? {
- if (appName != null) {
- return appName.toString()
- }
- return super.getAppName(context)
+ /**
+ * Returns the state int from [StatusBarManager] associated with the given sender state
+ * name.
+ *
+ * @param name the name of one of the [ChipStateReceiver] enums.
+ */
+ @StatusBarManager.MediaTransferReceiverState
+ fun getReceiverStateIdFromName(name: String): Int = valueOf(name).stateInt
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 1a96ddf69b28..44965d705802 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -18,15 +18,19 @@ package com.android.systemui.media.taptotransfer.receiver
import android.app.StatusBarManager
import android.content.Context
+import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.media.MediaRoute2Info
import android.os.Handler
+import android.os.PowerManager
import android.util.Log
import android.view.ViewGroup
import android.view.WindowManager
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
+import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.statusbar.CommandQueue
@@ -49,14 +53,17 @@ class MediaTttChipControllerReceiver @Inject constructor(
viewUtil: ViewUtil,
mainExecutor: DelayableExecutor,
tapGestureDetector: TapGestureDetector,
+ powerManager: PowerManager,
@Main private val mainHandler: Handler,
-) : MediaTttChipControllerCommon<ChipStateReceiver>(
+ private val uiEventLogger: MediaTttReceiverUiEventLogger,
+) : MediaTttChipControllerCommon<ChipReceiverInfo>(
context,
logger,
windowManager,
viewUtil,
mainExecutor,
tapGestureDetector,
+ powerManager,
R.layout.media_ttt_chip_receiver
) {
private val commandQueueCallbacks = object : CommandQueue.Callbacks {
@@ -82,45 +89,52 @@ class MediaTttChipControllerReceiver @Inject constructor(
appIcon: Icon?,
appName: CharSequence?
) {
- logger.logStateChange(stateIntToString(displayState), routeInfo.id)
- when(displayState) {
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER -> {
- val packageName = routeInfo.packageName
- if (appIcon == null) {
- displayChip(ChipStateReceiver(packageName, null, appName))
- } else {
- appIcon.loadDrawableAsync(
- context,
- Icon.OnDrawableLoadedListener { drawable ->
- displayChip(
- ChipStateReceiver(packageName, drawable, appName)
- )},
- // Notify the listener on the main handler since the listener will update
- // the UI.
- mainHandler
- )
- }
- }
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER ->
- removeChip(removalReason = FAR_FROM_SENDER)
- else ->
- Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState")
+ val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState)
+ val stateName = chipState?.name ?: "Invalid"
+ logger.logStateChange(stateName, routeInfo.id)
+
+ if (chipState == null) {
+ Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState")
+ return
+ }
+ uiEventLogger.logReceiverStateChange(chipState)
+
+ if (chipState == ChipStateReceiver.FAR_FROM_SENDER) {
+ removeChip(removalReason = ChipStateReceiver.FAR_FROM_SENDER::class.simpleName!!)
+ return
+ }
+ if (appIcon == null) {
+ displayChip(ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appName))
+ return
}
- }
- override fun updateChipView(chipState: ChipStateReceiver, currentChipView: ViewGroup) {
- setIcon(chipState, currentChipView)
+ appIcon.loadDrawableAsync(
+ context,
+ Icon.OnDrawableLoadedListener { drawable ->
+ displayChip(ChipReceiverInfo(routeInfo, drawable, appName))
+ },
+ // Notify the listener on the main handler since the listener will update
+ // the UI.
+ mainHandler
+ )
}
- private fun stateIntToString(@StatusBarManager.MediaTransferReceiverState state: Int): String {
- return when (state) {
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER -> CLOSE_TO_SENDER
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER -> FAR_FROM_SENDER
- else -> "INVALID: $state"
- }
+ override fun updateChipView(chipInfo: ChipReceiverInfo, currentChipView: ViewGroup) {
+ setIcon(
+ currentChipView,
+ chipInfo.routeInfo.packageName,
+ chipInfo.appIconDrawableOverride,
+ chipInfo.appNameOverride
+ )
}
}
+data class ChipReceiverInfo(
+ val routeInfo: MediaRoute2Info,
+ val appIconDrawableOverride: Drawable?,
+ val appNameOverride: CharSequence?
+) : ChipInfoCommon {
+ override fun getTimeoutMs() = DEFAULT_TIMEOUT_MILLIS
+}
+
private const val RECEIVER_TAG = "MediaTapToTransferRcvr"
-private const val CLOSE_TO_SENDER = "CLOSE_TO_SENDER"
-private const val FAR_FROM_SENDER = "FAR_FROM_SENDER"
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
new file mode 100644
index 000000000000..39a276329a9b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.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.systemui.media.taptotransfer.receiver
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** A class for analytics logging for the media tap-to-transfer chip on the receiver device. */
+@SysUISingleton
+class MediaTttReceiverUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
+ /** Logs that the receiver chip has changed states. */
+ fun logReceiverStateChange(chipState: ChipStateReceiver) {
+ logger.log(chipState.uiEvent)
+ }
+}
+
+enum class MediaTttReceiverUiEvents(val metricId: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+ MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER(982),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+ MEDIA_TTT_RECEIVER_FAR_FROM_SENDER(983);
+
+ override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index 22424a4e9c74..3c6805b4e881 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -16,188 +16,225 @@
package com.android.systemui.media.taptotransfer.sender
+import android.app.StatusBarManager
import android.content.Context
+import android.media.MediaRoute2Info
import android.view.View
+import androidx.annotation.StringRes
+import com.android.internal.logging.UiEventLogger
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
-import com.android.systemui.media.taptotransfer.common.MediaTttChipState
+import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
/**
- * A class that stores all the information necessary to display the media tap-to-transfer chip on
- * the sender device.
+ * A class enumerating all the possible states of the media tap-to-transfer chip on the sender
+ * device.
*
- * This is a sealed class where each subclass represents a specific chip state. Each subclass can
- * contain additional information that is necessary for only that state.
+ * @property stateInt the integer from [StatusBarManager] corresponding with this state.
+ * @property stringResId the res ID of the string that should be displayed in the chip. Null if the
+ * state should not have the chip be displayed.
+ * @property isMidTransfer true if the state represents that a transfer is currently ongoing.
+ * @property isTransferFailure true if the state represents that the transfer has failed.
+ * @property timeout the amount of time this chip should display on the screen before it times out
+ * and disappears.
*/
-sealed class ChipStateSender(
- appPackageName: String?
-) : MediaTttChipState(appPackageName) {
- /** Returns a fully-formed string with the text that the chip should display. */
- abstract fun getChipTextString(context: Context): String
-
- /** Returns true if the loading icon should be displayed and false otherwise. */
- open fun showLoading(): Boolean = false
-
+enum class ChipStateSender(
+ @StatusBarManager.MediaTransferSenderState val stateInt: Int,
+ val uiEvent: UiEventLogger.UiEventEnum,
+ @StringRes val stringResId: Int?,
+ val isMidTransfer: Boolean = false,
+ val isTransferFailure: Boolean = false,
+ val timeout: Long = DEFAULT_TIMEOUT_MILLIS
+) {
/**
- * Returns a click listener for the undo button on the chip. Returns null if this chip state
- * doesn't have an undo button.
- *
- * @param controllerSender passed as a parameter in case we want to display a new chip state
- * when undo is clicked.
+ * A state representing that the two devices are close but not close enough to *start* a cast to
+ * the receiver device. The chip will instruct the user to move closer in order to initiate the
+ * transfer to the receiver.
*/
- open fun undoClickListener(
- controllerSender: MediaTttChipControllerSender
- ): View.OnClickListener? = null
-}
-
-/**
- * A state representing that the two devices are close but not close enough to *start* a cast to
- * the receiver device. The chip will instruct the user to move closer in order to initiate the
- * transfer to the receiver.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class AlmostCloseToStartCast(
- appPackageName: String?,
- private val otherDeviceName: String,
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_move_closer_to_start_cast, otherDeviceName)
- }
-}
-
-/**
- * A state representing that the two devices are close but not close enough to *end* a cast that's
- * currently occurring the receiver device. The chip will instruct the user to move closer in order
- * to initiate the transfer from the receiver and back onto this device (the original sender).
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class AlmostCloseToEndCast(
- appPackageName: String?,
- private val otherDeviceName: String,
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_move_closer_to_end_cast, otherDeviceName)
- }
-}
-
-/**
- * A state representing that a transfer to the receiver device has been initiated (but not
- * completed).
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class TransferToReceiverTriggered(
- appPackageName: String?,
- private val otherDeviceName: String
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_transfer_playing_different_device, otherDeviceName)
- }
-
- override fun showLoading() = true
- override fun getTimeoutMs() = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
-}
+ ALMOST_CLOSE_TO_START_CAST(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST,
+ R.string.media_move_closer_to_start_cast,
+ ),
-/**
- * A state representing that a transfer from the receiver device and back to this device (the
- * sender) has been initiated (but not completed).
- */
-class TransferToThisDeviceTriggered(
- appPackageName: String?,
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_transfer_playing_this_device)
- }
+ /**
+ * A state representing that the two devices are close but not close enough to *end* a cast
+ * that's currently occurring the receiver device. The chip will instruct the user to move
+ * closer in order to initiate the transfer from the receiver and back onto this device (the
+ * original sender).
+ */
+ ALMOST_CLOSE_TO_END_CAST(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST,
+ R.string.media_move_closer_to_end_cast,
+ ),
- override fun showLoading() = true
- override fun getTimeoutMs() = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
-}
+ /**
+ * A state representing that a transfer to the receiver device has been initiated (but not
+ * completed).
+ */
+ TRANSFER_TO_RECEIVER_TRIGGERED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED,
+ R.string.media_transfer_playing_different_device,
+ isMidTransfer = true,
+ timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
+ ),
-/**
- * A state representing that a transfer to the receiver device has been successfully completed.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- * @property undoCallback if present, the callback that should be called when the user clicks the
- * undo button. The undo button will only be shown if this is non-null.
- */
-class TransferToReceiverSucceeded(
- appPackageName: String?,
- private val otherDeviceName: String,
- val undoCallback: IUndoMediaTransferCallback? = null
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_transfer_playing_different_device, otherDeviceName)
- }
+ /**
+ * A state representing that a transfer from the receiver device and back to this device (the
+ * sender) has been initiated (but not completed).
+ */
+ TRANSFER_TO_THIS_DEVICE_TRIGGERED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+ R.string.media_transfer_playing_this_device,
+ isMidTransfer = true,
+ timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
+ ),
- override fun undoClickListener(
- controllerSender: MediaTttChipControllerSender
- ): View.OnClickListener? {
- if (undoCallback == null) {
- return null
+ /**
+ * A state representing that a transfer to the receiver device has been successfully completed.
+ */
+ TRANSFER_TO_RECEIVER_SUCCEEDED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ R.string.media_transfer_playing_different_device
+ ) {
+ override fun undoClickListener(
+ controllerSender: MediaTttChipControllerSender,
+ routeInfo: MediaRoute2Info,
+ undoCallback: IUndoMediaTransferCallback?,
+ uiEventLogger: MediaTttSenderUiEventLogger
+ ): View.OnClickListener? {
+ if (undoCallback == null) {
+ return null
+ }
+ return View.OnClickListener {
+ uiEventLogger.logUndoClicked(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
+ )
+ undoCallback.onUndoTriggered()
+ // The external service should eventually send us a TransferToThisDeviceTriggered
+ // state, but that may take too long to go through the binder and the user may be
+ // confused ast o why the UI hasn't changed yet. So, we immediately change the UI
+ // here.
+ controllerSender.displayChip(
+ ChipSenderInfo(
+ TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, undoCallback
+ )
+ )
+ }
}
+ },
- return View.OnClickListener {
- this.undoCallback.onUndoTriggered()
- // The external service should eventually send us a TransferToThisDeviceTriggered state,
- // but that may take too long to go through the binder and the user may be confused as
- // to why the UI hasn't changed yet. So, we immediately change the UI here.
- controllerSender.displayChip(
- TransferToThisDeviceTriggered(this.appPackageName)
- )
+ /**
+ * A state representing that a transfer back to this device has been successfully completed.
+ */
+ TRANSFER_TO_THIS_DEVICE_SUCCEEDED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
+ R.string.media_transfer_playing_this_device
+ ) {
+ override fun undoClickListener(
+ controllerSender: MediaTttChipControllerSender,
+ routeInfo: MediaRoute2Info,
+ undoCallback: IUndoMediaTransferCallback?,
+ uiEventLogger: MediaTttSenderUiEventLogger
+ ): View.OnClickListener? {
+ if (undoCallback == null) {
+ return null
+ }
+ return View.OnClickListener {
+ uiEventLogger.logUndoClicked(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+ )
+ undoCallback.onUndoTriggered()
+ // The external service should eventually send us a TransferToReceiverTriggered
+ // state, but that may take too long to go through the binder and the user may be
+ // confused as to why the UI hasn't changed yet. So, we immediately change the UI
+ // here.
+ controllerSender.displayChip(
+ ChipSenderInfo(
+ TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, undoCallback
+ )
+ )
+ }
}
- }
-}
-
-/**
- * A state representing that a transfer back to this device has been successfully completed.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- * @property undoCallback if present, the callback that should be called when the user clicks the
- * undo button. The undo button will only be shown if this is non-null.
- */
-class TransferToThisDeviceSucceeded(
- appPackageName: String?,
- private val otherDeviceName: String,
- val undoCallback: IUndoMediaTransferCallback? = null
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_transfer_playing_this_device)
- }
+ },
+
+ /** A state representing that a transfer to the receiver device has failed. */
+ TRANSFER_TO_RECEIVER_FAILED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED,
+ R.string.media_transfer_failed,
+ isTransferFailure = true
+ ),
+
+ /** A state representing that a transfer back to this device has failed. */
+ TRANSFER_TO_THIS_DEVICE_FAILED(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED,
+ R.string.media_transfer_failed,
+ isTransferFailure = true
+ ),
+
+ /** A state representing that this device is far away from any receiver device. */
+ FAR_FROM_RECEIVER(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER,
+ stringResId = null
+ );
- override fun undoClickListener(
- controllerSender: MediaTttChipControllerSender
- ): View.OnClickListener? {
- if (undoCallback == null) {
+ /**
+ * Returns a fully-formed string with the text that the chip should display.
+ *
+ * @param otherDeviceName the name of the other device involved in the transfer.
+ */
+ fun getChipTextString(context: Context, otherDeviceName: String): String? {
+ if (stringResId == null) {
return null
}
-
- return View.OnClickListener {
- this.undoCallback.onUndoTriggered()
- // The external service should eventually send us a TransferToReceiverTriggered state,
- // but that may take too long to go through the binder and the user may be confused as
- // to why the UI hasn't changed yet. So, we immediately change the UI here.
- controllerSender.displayChip(
- TransferToReceiverTriggered(
- this.appPackageName,
- this.otherDeviceName
- )
- )
- }
+ return context.getString(stringResId, otherDeviceName)
}
-}
-/** A state representing that a transfer has failed. */
-class TransferFailed(
- appPackageName: String?,
-) : ChipStateSender(appPackageName) {
- override fun getChipTextString(context: Context): String {
- return context.getString(R.string.media_transfer_failed)
+ /**
+ * Returns a click listener for the undo button on the chip. Returns null if this chip state
+ * doesn't have an undo button.
+ *
+ * @param controllerSender passed as a parameter in case we want to display a new chip state
+ * when undo is clicked.
+ * @param undoCallback if present, the callback that should be called when the user clicks the
+ * undo button. The undo button will only be shown if this is non-null.
+ */
+ open fun undoClickListener(
+ controllerSender: MediaTttChipControllerSender,
+ routeInfo: MediaRoute2Info,
+ undoCallback: IUndoMediaTransferCallback?,
+ uiEventLogger: MediaTttSenderUiEventLogger
+ ): View.OnClickListener? = null
+
+ companion object {
+ /**
+ * Returns the sender state enum associated with the given [displayState] from
+ * [StatusBarManager].
+ */
+ fun getSenderStateFromId(
+ @StatusBarManager.MediaTransferSenderState displayState: Int,
+ ): ChipStateSender = values().first { it.stateInt == displayState }
+
+ /**
+ * Returns the state int from [StatusBarManager] associated with the given sender state
+ * name.
+ *
+ * @param name the name of one of the [ChipStateSender] enums.
+ */
+ @StatusBarManager.MediaTransferSenderState
+ fun getSenderStateIdFromName(name: String): Int = valueOf(name).stateInt
}
}
// Give the Transfer*Triggered states a longer timeout since those states represent an active
// process and we should keep the user informed about it as long as possible (but don't allow it to
// continue indefinitely).
-private const val TRANSFER_TRIGGERED_TIMEOUT_MILLIS = 15000L \ No newline at end of file
+private const val TRANSFER_TRIGGERED_TIMEOUT_MILLIS = 15000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index da2aac4d5ad7..9f5ec7e1a330 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -19,6 +19,7 @@ package com.android.systemui.media.taptotransfer.sender
import android.app.StatusBarManager
import android.content.Context
import android.media.MediaRoute2Info
+import android.os.PowerManager
import android.util.Log
import android.view.View
import android.view.ViewGroup
@@ -28,6 +29,7 @@ import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason
@@ -50,13 +52,16 @@ class MediaTttChipControllerSender @Inject constructor(
viewUtil: ViewUtil,
@Main mainExecutor: DelayableExecutor,
tapGestureDetector: TapGestureDetector,
-) : MediaTttChipControllerCommon<ChipStateSender>(
+ powerManager: PowerManager,
+ private val uiEventLogger: MediaTttSenderUiEventLogger
+) : MediaTttChipControllerCommon<ChipSenderInfo>(
context,
logger,
windowManager,
viewUtil,
mainExecutor,
tapGestureDetector,
+ powerManager,
R.layout.media_ttt_chip
) {
private var currentlyDisplayedChipState: ChipStateSender? = null
@@ -82,104 +87,83 @@ class MediaTttChipControllerSender @Inject constructor(
routeInfo: MediaRoute2Info,
undoCallback: IUndoMediaTransferCallback?
) {
- logger.logStateChange(stateIntToString(displayState), routeInfo.id)
- val appPackageName = routeInfo.packageName
- val otherDeviceName = routeInfo.name.toString()
- val chipState = when(displayState) {
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST ->
- AlmostCloseToStartCast(appPackageName, otherDeviceName)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST ->
- AlmostCloseToEndCast(appPackageName, otherDeviceName)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ->
- TransferToReceiverTriggered(appPackageName, otherDeviceName)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ->
- TransferToThisDeviceTriggered(appPackageName)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ->
- TransferToReceiverSucceeded(appPackageName, otherDeviceName, undoCallback)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED ->
- TransferToThisDeviceSucceeded(appPackageName, otherDeviceName, undoCallback)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED ->
- TransferFailed(appPackageName)
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER -> {
- removeChip(removalReason = FAR_FROM_RECEIVER)
- null
- }
- else -> {
- Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
- null
- }
+ val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState)
+ val stateName = chipState?.name ?: "Invalid"
+ logger.logStateChange(stateName, routeInfo.id)
+
+ if (chipState == null) {
+ Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
+ return
}
+ uiEventLogger.logSenderStateChange(chipState)
- chipState?.let {
- displayChip(it)
+ if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
+ removeChip(removalReason = ChipStateSender.FAR_FROM_RECEIVER::class.simpleName!!)
+ } else {
+ displayChip(ChipSenderInfo(chipState, routeInfo, undoCallback))
}
}
/** Displays the chip view for the given state. */
- override fun updateChipView(chipState: ChipStateSender, currentChipView: ViewGroup) {
+ override fun updateChipView(
+ chipInfo: ChipSenderInfo,
+ currentChipView: ViewGroup) {
+ val chipState = chipInfo.state
currentlyDisplayedChipState = chipState
// App icon
- setIcon(chipState, currentChipView)
+ setIcon(currentChipView, chipInfo.routeInfo.packageName)
// Text
+ val otherDeviceName = chipInfo.routeInfo.name.toString()
currentChipView.requireViewById<TextView>(R.id.text).apply {
- text = chipState.getChipTextString(context)
+ text = chipState.getChipTextString(context, otherDeviceName)
}
// Loading
currentChipView.requireViewById<View>(R.id.loading).visibility =
- if (chipState.showLoading()) { View.VISIBLE } else { View.GONE }
+ chipState.isMidTransfer.visibleIfTrue()
+
// Undo
val undoView = currentChipView.requireViewById<View>(R.id.undo)
- val undoClickListener = chipState.undoClickListener(this)
+ val undoClickListener = chipState.undoClickListener(
+ this, chipInfo.routeInfo, chipInfo.undoCallback, uiEventLogger
+ )
undoView.setOnClickListener(undoClickListener)
- undoView.visibility = if (undoClickListener != null) { View.VISIBLE } else { View.GONE }
+ undoView.visibility = (undoClickListener != null).visibleIfTrue()
// Failure
- val showFailure = chipState is TransferFailed
currentChipView.requireViewById<View>(R.id.failure_icon).visibility =
- if (showFailure) { View.VISIBLE } else { View.GONE }
+ chipState.isTransferFailure.visibleIfTrue()
}
override fun removeChip(removalReason: String) {
// Don't remove the chip if we're mid-transfer since the user should still be able to
// see the status of the transfer. (But do remove it if it's finally timed out.)
- if ((currentlyDisplayedChipState is TransferToReceiverTriggered ||
- currentlyDisplayedChipState is TransferToThisDeviceTriggered)
- && removalReason != MediaTttRemovalReason.REASON_TIMEOUT) {
+ if (currentlyDisplayedChipState?.isMidTransfer == true
+ && removalReason != MediaTttRemovalReason.REASON_TIMEOUT) {
return
}
super.removeChip(removalReason)
currentlyDisplayedChipState = null
}
- private fun stateIntToString(@StatusBarManager.MediaTransferSenderState state: Int): String {
- return when(state) {
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST ->
- "ALMOST_CLOSE_TO_START_CAST"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST ->
- "ALMOST_CLOSE_TO_END_CAST"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ->
- "TRANSFER_TO_RECEIVER_TRIGGERED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ->
- "TRANSFER_TO_THIS_DEVICE_TRIGGERED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ->
- "TRANSFER_TO_RECEIVER_SUCCEEDED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED ->
- "TRANSFER_TO_THIS_DEVICE_SUCCEEDED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED ->
- "TRANSFER_TO_RECEIVER_FAILED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED ->
- "TRANSFER_TO_THIS_DEVICE_FAILED"
- StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER ->
- FAR_FROM_RECEIVER
- else -> "INVALID: $state"
+ private fun Boolean.visibleIfTrue(): Int {
+ return if (this) {
+ View.VISIBLE
+ } else {
+ View.GONE
}
}
}
+data class ChipSenderInfo(
+ val state: ChipStateSender,
+ val routeInfo: MediaRoute2Info,
+ val undoCallback: IUndoMediaTransferCallback? = null
+) : ChipInfoCommon {
+ override fun getTimeoutMs() = state.timeout
+}
+
const val SENDER_TAG = "MediaTapToTransferSender"
-private const val FAR_FROM_RECEIVER = "FAR_FROM_RECEIVER"
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
new file mode 100644
index 000000000000..af3c1b60bacf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.taptotransfer.sender
+
+import android.util.Log
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** A class for analytics logging for the media tap-to-transfer chip on the sender device. */
+@SysUISingleton
+class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
+ /** Logs that the sender chip has changed states. */
+ fun logSenderStateChange(chipState: ChipStateSender) {
+ logger.log(chipState.uiEvent)
+ }
+
+ /**
+ * Logs that the undo button was clicked.
+ *
+ * @param undoUiEvent the uiEvent specific to which undo button was clicked.
+ */
+ fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum) {
+ val isUndoEvent =
+ undoUiEvent == MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
+ || undoUiEvent ==
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+ if (!isUndoEvent) {
+ Log.w(
+ MediaTttSenderUiEventLogger::class.simpleName!!,
+ "Must pass an undo-specific UiEvent."
+ )
+ return
+ }
+ logger.log(undoUiEvent)
+ }
+}
+
+enum class MediaTttSenderUiEvents(val metricId: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The undo button on the media ttt chip on the sender device was clicked " +
+ "to undo the transfer to the receiver device")
+ MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED(971),
+ @UiEvent(doc = "The undo button on the media ttt chip on the sender device was clicked " +
+ "to undo the transfer back to this device")
+ MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED(972),
+
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST(973),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST(974),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED(975),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED(976),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED(977),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED(978),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED(979),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED(980),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+ MEDIA_TTT_SENDER_FAR_FROM_RECEIVER(981);
+
+ override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 039c33315741..b4e20fd7f32b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -97,7 +97,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
"SHOWING_AUTO_SAVER_SUGGESTION",
};
- private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
+ private static final String ACTION_SHOW_BATTERY_SAVER_SETTINGS = "PNW.batterySaverSettings";
private static final String ACTION_START_SAVER = "PNW.startSaver";
private static final String ACTION_DISMISSED_WARNING = "PNW.dismissedWarning";
private static final String ACTION_CLICKED_TEMP_WARNING = "PNW.clickedTempWarning";
@@ -120,8 +120,6 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private static final String ACTION_ENABLE_SEVERE_BATTERY_DIALOG = "PNW.enableSevereDialog";
- private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
- "android.settings.BATTERY_SAVER_SETTINGS";
public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION =
"com.android.settings.BATTERY_SAVER_SCHEDULE_SETTINGS";
@@ -140,6 +138,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Receiver mReceiver = new Receiver();
private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
+ private final Intent mOpenBatterySaverSettings =
+ settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+ private final boolean mUseSevereDialog;
private int mBatteryLevel;
private int mBucket;
@@ -170,6 +171,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
mKeyguard = mContext.getSystemService(KeyguardManager.class);
mReceiver.init();
mActivityStarter = activityStarter;
+ mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
}
@Override
@@ -283,11 +285,11 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
.setContentText(contentText)
.setContentTitle(title)
.setOnlyAlertOnce(true)
- .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
+ .setOngoing(true)
.setStyle(new Notification.BigTextStyle().bigText(contentText))
.setVisibility(Notification.VISIBILITY_PUBLIC);
if (hasBatterySettings()) {
- nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
+ nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SAVER_SETTINGS));
}
// Make the notification red if the percentage goes below a certain amount or the time
// remaining estimate is disabled
@@ -298,6 +300,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
}
if (!mPowerMan.isPowerSaveMode()) {
+ nb.addAction(0, mContext.getString(R.string.battery_saver_dismiss_action),
+ pendingBroadcast(ACTION_DISMISSED_WARNING));
nb.addAction(0,
mContext.getString(R.string.battery_saver_start_action),
pendingBroadcast(ACTION_START_SAVER));
@@ -312,9 +316,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private boolean showSevereLowBatteryDialog() {
final boolean isSevereState = !mCurrentBatterySnapshot.isHybrid() || mBucket < -1;
- final boolean useSevereDialog = mContext.getResources().getBoolean(
- R.bool.config_severe_battery_dialog);
- return isSevereState && useSevereDialog;
+ return isSevereState && mUseSevereDialog;
}
private void showAutoSaverSuggestionNotification() {
@@ -748,7 +750,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
public void init() {
IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
+ filter.addAction(ACTION_SHOW_BATTERY_SAVER_SETTINGS);
filter.addAction(ACTION_START_SAVER);
filter.addAction(ACTION_DISMISSED_WARNING);
filter.addAction(ACTION_CLICKED_TEMP_WARNING);
@@ -768,9 +770,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Slog.i(TAG, "Received " + action);
- if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
+ if (action.equals(ACTION_SHOW_BATTERY_SAVER_SETTINGS)) {
dismissLowBatteryNotification();
- mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
+ mContext.startActivityAsUser(mOpenBatterySaverSettings, UserHandle.CURRENT);
} else if (action.equals(ACTION_START_SAVER)) {
setSaverMode(true, true);
dismissLowBatteryNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 56528c9974ac..61b434d6a28f 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -51,7 +51,6 @@ import com.android.systemui.statusbar.phone.CentralSurfaces;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.time.Duration;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.Future;
@@ -70,7 +69,6 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
static final long THREE_HOURS_IN_MILLIS = DateUtils.HOUR_IN_MILLIS * 3;
private static final int CHARGE_CYCLE_PERCENT_RESET = 30;
- private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis();
public static final int NO_ESTIMATE_AVAILABLE = -1;
private static final String BOOT_COUNT_KEY = "boot_count";
private static final String PREFS = "powerui_prefs";
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 5d9361d201c1..e0d158cd7db6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -18,7 +18,10 @@ package com.android.systemui.qs
import android.app.IActivityManager
import android.app.IForegroundServiceObserver
+import android.content.BroadcastReceiver
import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.IBinder
@@ -42,6 +45,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -67,6 +71,7 @@ class FgsManagerController @Inject constructor(
private val packageManager: PackageManager,
private val deviceConfigProxy: DeviceConfigProxy,
private val dialogLaunchAnimator: DialogLaunchAnimator,
+ private val broadcastDispatcher: BroadcastDispatcher,
private val dumpManager: DumpManager
) : IForegroundServiceObserver.Stub(), Dumpable {
@@ -125,6 +130,18 @@ class FgsManagerController @Inject constructor(
dumpManager.registerDumpable(this)
+ broadcastDispatcher.registerReceiver(
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.action == Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER) {
+ showDialog(null)
+ }
+ }
+ },
+ IntentFilter(Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER),
+ executor = mainExecutor,
+ flags = Context.RECEIVER_NOT_EXPORTED)
+
initialized = true
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 00142799c541..865f09337fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -199,9 +199,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
/** */
public void setListening(boolean listening, boolean expanded) {
- // TODO(218268829): checking for split shade is workaround but when proper fix lands
- // "|| mShouldUseSplitNotificationShade" should be removed
- setListening(listening && (expanded || mShouldUseSplitNotificationShade));
+ setListening(listening && expanded);
if (mView.isListening()) {
refreshAllTiles();
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 4a9a1f1f055d..6d729b92e7b8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -403,12 +403,24 @@ public class ScreenshotView extends FrameLayout implements
}
@Override
- public void onDismiss() {
+ public void onSwipeDismissInitiated(Animator anim) {
if (DEBUG_DISMISS) {
Log.d(ScreenshotView.TAG, "dismiss triggered via swipe gesture");
}
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
mPackageName);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mBackgroundProtection.animate()
+ .alpha(0).setDuration(anim.getDuration()).start();
+ }
+ });
+ }
+
+ @Override
+ public void onDismissComplete() {
mCallbacks.onDismiss();
}
});
@@ -995,6 +1007,7 @@ public class ScreenshotView extends FrameLayout implements
mSmartChips.clear();
mQuickShareChip = null;
setAlpha(1);
+ mScreenshotStatic.setAlpha(1);
mScreenshotSelectorView.stop();
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java b/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
index 451fb1311ebb..24b1249c3f98 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
@@ -49,9 +49,14 @@ public class SwipeDismissHandler implements View.OnTouchListener {
void onInteraction();
/**
+ * Run when the view is dismissed (the distance threshold is met), pre-dismissal animation
+ */
+ void onSwipeDismissInitiated(Animator animator);
+
+ /**
* Run when the view is dismissed (the distance threshold is met), post-dismissal animation
*/
- void onDismiss();
+ void onDismissComplete();
}
private final View mView;
@@ -89,7 +94,9 @@ public class SwipeDismissHandler implements View.OnTouchListener {
return true;
}
if (isPastDismissThreshold()) {
- dismiss();
+ ValueAnimator dismissAnimator = createSwipeDismissAnimation(1);
+ mCallbacks.onSwipeDismissInitiated(dismissAnimator);
+ dismiss(dismissAnimator);
} else {
// if we've moved, but not past the threshold, start the return animation
if (DEBUG_DISMISS) {
@@ -117,7 +124,10 @@ public class SwipeDismissHandler implements View.OnTouchListener {
float velocityY) {
if (mView.getTranslationX() * velocityX > 0
&& (mDismissAnimation == null || !mDismissAnimation.isRunning())) {
- dismiss(velocityX / (float) 1000);
+ ValueAnimator dismissAnimator =
+ createSwipeDismissAnimation(velocityX / (float) 1000);
+ mCallbacks.onSwipeDismissInitiated(dismissAnimator);
+ dismiss(dismissAnimator);
return true;
}
return false;
@@ -160,11 +170,11 @@ public class SwipeDismissHandler implements View.OnTouchListener {
* Start dismissal animation (will run onDismiss callback when animation complete)
*/
public void dismiss() {
- dismiss(1);
+ dismiss(createSwipeDismissAnimation(1));
}
- private void dismiss(float velocity) {
- mDismissAnimation = createSwipeDismissAnimation(velocity);
+ private void dismiss(ValueAnimator animator) {
+ mDismissAnimation = animator;
mDismissAnimation.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
@@ -178,7 +188,7 @@ public class SwipeDismissHandler implements View.OnTouchListener {
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (!mCancelled) {
- mCallbacks.onDismiss();
+ mCallbacks.onDismissComplete();
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
new file mode 100644
index 000000000000..aa2bcecbd224
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.smartspace
+
+/**
+ * A {@link SmartspacePrecondition} captures the conditions that must be met for Smartspace to be
+ * used in a particular setting.
+ */
+interface SmartspacePrecondition {
+ /**
+ * A callback for receiving updates when conditions have changed.
+ */
+ interface Listener {
+ fun onCriteriaChanged()
+ }
+
+ /**
+ * Adds a listener to receive future updates. {@link Listener#onCriteriaChanged} will be called
+ * immediately upon adding.
+ */
+ fun addListener(listener: Listener)
+
+ /**
+ * Removes a listener from receiving future updates.
+ */
+ fun removeListener(listener: Listener)
+
+ /**
+ * Returns whether all conditions have been met.
+ */
+ fun conditionsMet(): Boolean
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
new file mode 100644
index 000000000000..7228550e4e41
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceTarget
+
+/**
+ * {@link SmartspaceTargetFilter} defines a way to locally filter targets from inclusion. This
+ * should be used for filtering that isn't available further upstream.
+ */
+interface SmartspaceTargetFilter {
+ /**
+ * An interface implemented by clients to receive updates when the filtering criteria changes.
+ * When this happens, the client should refresh their target set.
+ */
+ interface Listener {
+ fun onCriteriaChanged()
+ }
+
+ /**
+ * Adds a listener to receive future updates. {@link Listener#onCriteriaChanged} will be
+ * invoked immediately after.
+ */
+ fun addListener(listener: Listener)
+
+ /**
+ * Removes listener from receiving future updates.
+ */
+ fun removeListener(listener: Listener)
+
+ /**
+ * Returns {@code true} if the {@link SmartspaceTarget} should be included in the current
+ * target set, {@code false} otherwise.
+ */
+ fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
new file mode 100644
index 000000000000..1b74ac36ebf0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.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.systemui.smartspace.dagger
+
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.smartspace.filters.LockscreenTargetFilter
+import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
+import dagger.Binds
+import dagger.BindsOptionalOf
+import dagger.Module
+import javax.inject.Named
+
+@Module(subcomponents = [SmartspaceViewComponent::class])
+abstract class SmartspaceModule {
+ @Module
+ companion object {
+ /**
+ * The BcSmartspaceDataProvider for dreams.
+ */
+ const val DREAM_SMARTSPACE_DATA_PLUGIN = "dreams_smartspace_data_plugin"
+
+ /**
+ * The lockscreen smartspace target filter.
+ */
+ const val LOCKSCREEN_SMARTSPACE_TARGET_FILTER = "lockscreen_smartspace_target_filter"
+
+ /**
+ * The dream smartspace target filter.
+ */
+ const val DREAM_SMARTSPACE_TARGET_FILTER = "dream_smartspace_target_filter"
+
+ /**
+ * The precondition for dream smartspace
+ */
+ const val DREAM_SMARTSPACE_PRECONDITION = "dream_smartspace_precondition"
+ }
+
+ @BindsOptionalOf
+ @Named(DREAM_SMARTSPACE_TARGET_FILTER)
+ abstract fun optionalDreamSmartspaceTargetFilter(): SmartspaceTargetFilter?
+
+ @BindsOptionalOf
+ @Named(DREAM_SMARTSPACE_DATA_PLUGIN)
+ abstract fun optionalDreamsBcSmartspaceDataPlugin(): BcSmartspaceDataPlugin?
+
+ @Binds
+ @Named(LOCKSCREEN_SMARTSPACE_TARGET_FILTER)
+ abstract fun provideLockscreenSmartspaceTargetFilter(
+ filter: LockscreenTargetFilter?
+ ): SmartspaceTargetFilter?
+
+ @Binds
+ @Named(DREAM_SMARTSPACE_PRECONDITION)
+ abstract fun bindSmartspacePrecondition(
+ lockscreenPrecondition: LockscreenPrecondition?
+ ): SmartspacePrecondition?
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
new file mode 100644
index 000000000000..d3ae198e8e35
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.smartspace.dagger
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent.SmartspaceViewModule.PLUGIN
+import dagger.BindsInstance
+import dagger.Module
+import dagger.Provides
+import dagger.Subcomponent
+import javax.inject.Named
+
+@Subcomponent(modules = [SmartspaceViewComponent.SmartspaceViewModule::class])
+interface SmartspaceViewComponent {
+ @Subcomponent.Factory
+ interface Factory {
+ fun create(
+ @BindsInstance parent: ViewGroup,
+ @BindsInstance @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
+ @BindsInstance onAttachListener: View.OnAttachStateChangeListener
+ ): SmartspaceViewComponent
+ }
+
+ fun getView(): BcSmartspaceDataPlugin.SmartspaceView
+
+ @Module
+ object SmartspaceViewModule {
+ const val PLUGIN = "plugin"
+
+ @Provides
+ fun providesSmartspaceView(
+ activityStarter: ActivityStarter,
+ falsingManager: FalsingManager,
+ parent: ViewGroup,
+ @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
+ onAttachListener: View.OnAttachStateChangeListener
+ ):
+ BcSmartspaceDataPlugin.SmartspaceView {
+ val ssView = plugin.getView(parent)
+ ssView.registerDataProvider(plugin)
+
+ ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
+ override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
+ activityStarter.startActivity(
+ intent,
+ true, /* dismissShade */
+ null, /* launch animator */
+ showOnLockscreen
+ )
+ }
+
+ override fun startPendingIntent(pi: PendingIntent, showOnLockscreen: Boolean) {
+ if (showOnLockscreen) {
+ pi.send()
+ } else {
+ activityStarter.startPendingIntentDismissingKeyguard(pi)
+ }
+ }
+ })
+ (ssView as View).addOnAttachStateChangeListener(onAttachListener)
+ ssView.setFalsingManager(falsingManager)
+ return ssView
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt b/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt
new file mode 100644
index 000000000000..6ad490169c17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt
@@ -0,0 +1,152 @@
+/*
+ * 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.smartspace.filters
+
+import android.app.smartspace.SmartspaceTarget
+import android.content.ContentResolver
+import android.content.Context
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.settings.SecureSettings
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * {@link SmartspaceTargetFilter} for smartspace targets that show above the lockscreen.
+ */
+class LockscreenTargetFilter @Inject constructor(
+ private val secureSettings: SecureSettings,
+ private val userTracker: UserTracker,
+ private val execution: Execution,
+ @Main private val handler: Handler,
+ private val contentResolver: ContentResolver,
+ @Main private val uiExecutor: Executor
+) : SmartspaceTargetFilter {
+ private var listeners: MutableSet<SmartspaceTargetFilter.Listener> = mutableSetOf()
+ private var showSensitiveContentForCurrentUser = false
+ set(value) {
+ val existing = field
+ field = value
+ if (existing != field) {
+ listeners.forEach { it.onCriteriaChanged() }
+ }
+ }
+ private var showSensitiveContentForManagedUser = false
+ set(value) {
+ val existing = field
+ field = value
+ if (existing != field) {
+ listeners.forEach { it.onCriteriaChanged() }
+ }
+ }
+
+ private val settingsObserver = object : ContentObserver(handler) {
+ override fun onChange(selfChange: Boolean, uri: Uri?) {
+ execution.assertIsMainThread()
+ updateUserContentSettings()
+ }
+ }
+
+ private var managedUserHandle: UserHandle? = null
+
+ override fun addListener(listener: SmartspaceTargetFilter.Listener) {
+ listeners.add(listener)
+
+ if (listeners.size != 1) {
+ return
+ }
+
+ userTracker.addCallback(userTrackerCallback, uiExecutor)
+
+ contentResolver.registerContentObserver(
+ secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+ true,
+ settingsObserver,
+ UserHandle.USER_ALL
+ )
+
+ updateUserContentSettings()
+ }
+
+ override fun removeListener(listener: SmartspaceTargetFilter.Listener) {
+ listeners.remove(listener)
+
+ if (listeners.isNotEmpty()) {
+ return
+ }
+
+ userTracker.removeCallback(userTrackerCallback)
+ contentResolver.unregisterContentObserver(settingsObserver)
+ }
+
+ override fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean {
+ return when (t.userHandle) {
+ userTracker.userHandle -> {
+ !t.isSensitive || showSensitiveContentForCurrentUser
+ }
+ managedUserHandle -> {
+ // Really, this should be "if this managed profile is associated with the current
+ // active user", but we don't have a good way to check that, so instead we cheat:
+ // Only the primary user can have an associated managed profile, so only show
+ // content for the managed profile if the primary user is active
+ userTracker.userHandle.identifier == UserHandle.USER_SYSTEM &&
+ (!t.isSensitive || showSensitiveContentForManagedUser)
+ }
+ else -> {
+ false
+ }
+ }
+ }
+
+ private val userTrackerCallback = object : UserTracker.Callback {
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ execution.assertIsMainThread()
+ updateUserContentSettings()
+ }
+ }
+
+ private fun getWorkProfileUser(): UserHandle? {
+ for (userInfo in userTracker.userProfiles) {
+ if (userInfo.isManagedProfile) {
+ return userInfo.userHandle
+ }
+ }
+ return null
+ }
+
+ private fun updateUserContentSettings() {
+ val setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+
+ showSensitiveContentForCurrentUser =
+ secureSettings.getIntForUser(setting, 0, userTracker.userId) == 1
+
+ managedUserHandle = getWorkProfileUser()
+ val managedId = managedUserHandle?.identifier
+ if (managedId != null) {
+ showSensitiveContentForManagedUser =
+ secureSettings.getIntForUser(setting, 0, managedId) == 1
+ }
+
+ listeners.forEach { it.onCriteriaChanged() }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt b/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
new file mode 100644
index 000000000000..1302ec9dbc55
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.smartspace.preconditions
+
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.util.concurrency.Execution
+import javax.inject.Inject
+
+/**
+ * {@link LockscreenPrecondition} covers the conditions that must be met before Smartspace can be
+ * used over lockscreen. These conditions include the device being provisioned with a setup user
+ * and the Smartspace feature flag enabled.
+ */
+class LockscreenPrecondition @Inject constructor(
+ private val featureFlags: FeatureFlags,
+ private val deviceProvisionedController: DeviceProvisionedController,
+ private val execution: Execution
+) : SmartspacePrecondition {
+ private var listeners = mutableSetOf<SmartspacePrecondition.Listener>()
+
+ private val deviceProvisionedListener =
+ object : DeviceProvisionedController.DeviceProvisionedListener {
+ override fun onDeviceProvisionedChanged() {
+ updateDeviceReadiness()
+ }
+
+ override fun onUserSetupChanged() {
+ updateDeviceReadiness()
+ }
+ }
+
+ init {
+ deviceProvisionedController.addCallback(deviceProvisionedListener)
+ }
+
+ var deviceReady: Boolean = false
+ private set
+
+ init {
+ updateDeviceReadiness()
+ }
+
+ private fun updateDeviceReadiness() {
+ if (deviceReady) {
+ return
+ }
+
+ deviceReady = deviceProvisionedController.isDeviceProvisioned &&
+ deviceProvisionedController.isCurrentUserSetup
+
+ if (!deviceReady) {
+ return
+ }
+
+ deviceProvisionedController.removeCallback(deviceProvisionedListener)
+ synchronized(listeners) {
+ listeners.forEach { it.onCriteriaChanged() }
+ }
+ }
+
+ override fun addListener(listener: SmartspacePrecondition.Listener) {
+ synchronized(listeners) {
+ listeners += listener
+ }
+ // Always trigger a targeted callback upon addition of listener.
+ listener.onCriteriaChanged()
+ }
+
+ override fun removeListener(listener: SmartspacePrecondition.Listener) {
+ synchronized(listeners) {
+ listeners -= listener
+ }
+ }
+
+ override fun conditionsMet(): Boolean {
+ execution.assertIsMainThread()
+ return featureFlags.isEnabled(Flags.SMARTSPACE) && deviceReady
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 17f42b1a3a43..1ab03455cca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -99,15 +99,57 @@ class LockscreenShadeTransitionController @Inject constructor(
internal var pulseHeightAnimator: ValueAnimator? = null
/**
- * Distance that the full shade transition takes in order for scrim to fully transition to
- * the shade (in alpha)
+ * Distance that the full shade transition takes in order to complete.
+ */
+ private var fullTransitionDistance = 0
+
+ /**
+ * Distance that the full transition takes in order for us to fully transition to the shade by
+ * tapping on a button, such as "expand".
+ */
+ private var fullTransitionDistanceByTap = 0
+
+ /**
+ * Distance that the full shade transition takes in order for scrim to fully transition to the
+ * shade (in alpha)
*/
private var scrimTransitionDistance = 0
/**
- * Distance that the full transition takes in order for us to fully transition to the shade
+ * Distance that the full shade transition takes in order for the notification shelf to fully
+ * expand.
*/
- private var fullTransitionDistance = 0
+ private var notificationShelfTransitionDistance = 0
+
+ /**
+ * Distance that the full shade transition takes in order for the Quick Settings to fully fade
+ * and expand.
+ */
+ private var qsTransitionDistance = 0
+
+ /**
+ * Distance that the full shade transition takes in order for the keyguard content on
+ * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
+ */
+ private var npvcKeyguardContentAlphaTransitionDistance = 0
+
+ /**
+ * Distance that the full shade transition takes in order for depth of the wallpaper to fully
+ * change.
+ */
+ private var depthControllerTransitionDistance = 0
+
+ /**
+ * Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+ * fade.
+ */
+ private var udfpsTransitionDistance = 0
+
+ /**
+ * Used for StatusBar to know that a transition is in progress. At the moment it only checks
+ * whether the progress is > 0, therefore this value is not very important.
+ */
+ private var statusBarTransitionDistance = 0
/**
* Flag to make sure that the dragDownAmount is applied to the listeners even when in the
@@ -130,7 +172,7 @@ class LockscreenShadeTransitionController @Inject constructor(
* The distance until we're showing the notifications when pulsing
*/
val distanceUntilShowingPulsingNotifications
- get() = scrimTransitionDistance
+ get() = fullTransitionDistance
/**
* The udfpsKeyguardViewController if it exists.
@@ -177,10 +219,24 @@ class LockscreenShadeTransitionController @Inject constructor(
}
private fun updateResources() {
+ fullTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_full_transition_distance)
+ fullTransitionDistanceByTap = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_transition_by_tap_distance)
scrimTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_scrim_transition_distance)
- fullTransitionDistance = context.resources.getDimensionPixelSize(
+ notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_notif_shelf_transition_distance)
+ qsTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_qs_transition_distance)
+ npvcKeyguardContentAlphaTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+ depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_depth_controller_transition_distance)
+ udfpsTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_udfps_keyguard_transition_distance)
+ statusBarTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_status_bar_transition_distance)
useSplitShade = Utils.shouldUseSplitNotificationShade(context.resources)
}
@@ -248,6 +304,7 @@ class LockscreenShadeTransitionController @Inject constructor(
// override that
forceApplyAmount = true
// Reset the behavior. At this point the animation is already started
+ logger.logDragDownAmountReset()
dragDownAmount = 0f
forceApplyAmount = false
}
@@ -337,11 +394,16 @@ class LockscreenShadeTransitionController @Inject constructor(
if (field != value || forceApplyAmount) {
field = value
if (!nsslController.isInLockedDownShade() || field == 0f || forceApplyAmount) {
- qSDragProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
- nsslController.setTransitionToFullShadeAmount(field, qSDragProgress)
+ val notificationShelfProgress =
+ MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
+ nsslController.setTransitionToFullShadeAmount(field, notificationShelfProgress)
+
+ qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
qS.setTransitionToFullShadeAmount(field, qSDragProgress)
+
notificationPanelController.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */)
+
mediaHierarchyManager.setTransitionToFullShadeAmount(field)
transitionToShadeAmountCommon(field)
}
@@ -357,11 +419,23 @@ class LockscreenShadeTransitionController @Inject constructor(
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
scrimController.setTransitionToFullShadeProgress(scrimProgress)
+
// Fade out all content only visible on the lockscreen
- notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
- depthController.transitionToFullShadeProgress = scrimProgress
- udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
- centralSurfaces.setTransitionToFullShadeProgress(scrimProgress)
+ val npvcProgress =
+ MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
+ notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - npvcProgress)
+
+ if (depthControllerTransitionDistance > 0) {
+ val depthProgress =
+ MathUtils.saturate(dragDownAmount / depthControllerTransitionDistance)
+ depthController.transitionToFullShadeProgress = depthProgress
+ }
+
+ val udfpsProgress = MathUtils.saturate(dragDownAmount / udfpsTransitionDistance)
+ udfpsKeyguardViewController?.setTransitionToFullShadeProgress(udfpsProgress)
+
+ val statusBarProgress = MathUtils.saturate(dragDownAmount / statusBarTransitionDistance)
+ centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress)
}
private fun setDragDownAmountAnimated(
@@ -404,9 +478,10 @@ class LockscreenShadeTransitionController @Inject constructor(
// be a couple of frames later. if we're setting it to 0, it will use the
// default inset and therefore flicker
dragDownAmount = 1f
- setDragDownAmountAnimated(fullTransitionDistance.toFloat(), delay = delay) {
+ setDragDownAmountAnimated(fullTransitionDistanceByTap.toFloat(), delay = delay) {
// End listener:
// Reset
+ logger.logDragDownAmountReset()
dragDownAmount = 0f
forceApplyAmount = false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt
new file mode 100644
index 000000000000..b54163d29e80
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEvents
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+
+/** Extends the lifetime of notifications while their activity launch animation is playing. */
+interface ActivityLaunchAnimCoordinator : Coordinator
+
+/** Provides an [ActivityLaunchAnimCoordinator] to [CoordinatorScope]. */
+@Module(includes = [PrivateActivityStarterCoordinatorModule::class])
+object ActivityLaunchAnimCoordinatorModule
+
+@Module
+private interface PrivateActivityStarterCoordinatorModule {
+ @Binds
+ fun bindCoordinator(impl: ActivityLaunchAnimCoordinatorImpl): ActivityLaunchAnimCoordinator
+}
+
+/**
+ * Listens for [NotifActivityLaunchEvents], and then extends the lifetimes of any notifs while their
+ * launch animation is playing.
+ */
+@CoordinatorScope
+private class ActivityLaunchAnimCoordinatorImpl @Inject constructor(
+ private val activityLaunchEvents: NotifActivityLaunchEvents
+) : ActivityLaunchAnimCoordinator {
+ // Tracks notification launches, and whether or not their lifetimes are extended.
+ private val notifsLaunchingActivities = mutableMapOf<String, Boolean>()
+
+ private var onEndLifetimeExtensionCallback: OnEndLifetimeExtensionCallback? = null
+
+ override fun attach(pipeline: NotifPipeline) {
+ activityLaunchEvents.registerListener(activityStartEventListener)
+ pipeline.addNotificationLifetimeExtender(extender)
+ }
+
+ private val activityStartEventListener = object : NotifActivityLaunchEvents.Listener {
+ override fun onStartLaunchNotifActivity(entry: NotificationEntry) {
+ notifsLaunchingActivities[entry.key] = false
+ }
+
+ override fun onFinishLaunchNotifActivity(entry: NotificationEntry) {
+ if (notifsLaunchingActivities.remove(entry.key) == true) {
+ // If we were extending the lifetime of this notification, stop.
+ onEndLifetimeExtensionCallback?.onEndLifetimeExtension(extender, entry)
+ }
+ }
+ }
+
+ private val extender = object : NotifLifetimeExtender {
+ override fun getName(): String = "ActivityStarterCoordinator"
+
+ override fun setCallback(callback: OnEndLifetimeExtensionCallback) {
+ onEndLifetimeExtensionCallback = callback
+ }
+
+ override fun maybeExtendLifetime(entry: NotificationEntry, reason: Int): Boolean {
+ if (entry.key in notifsLaunchingActivities) {
+ // Track that we're now extending this notif
+ notifsLaunchingActivities[entry.key] = true
+ return true
+ }
+ return false
+ }
+
+ override fun cancelLifetimeExtension(entry: NotificationEntry) {
+ if (entry.key in notifsLaunchingActivities) {
+ notifsLaunchingActivities[entry.key] = false
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java
deleted file mode 100644
index 5396b8638225..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.coordinator;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * {@link CommunalCoordinator} prevents notifications from showing on the keyguard when the communal
- * view is present.
- */
-@CoordinatorScope
-public class CommunalCoordinator implements Coordinator {
- final Executor mExecutor;
- final CommunalStateController mCommunalStateController;
- final NotificationEntryManager mNotificationEntryManager;
- final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
-
- @Inject
- public CommunalCoordinator(@Main Executor executor,
- NotificationEntryManager notificationEntryManager,
- NotificationLockscreenUserManager notificationLockscreenUserManager,
- CommunalStateController communalStateController) {
- mExecutor = executor;
- mNotificationEntryManager = notificationEntryManager;
- mNotificationLockscreenUserManager = notificationLockscreenUserManager;
- mCommunalStateController = communalStateController;
- }
-
- final NotifFilter mFilter = new NotifFilter("CommunalCoordinator") {
- @Override
- public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) {
- return mCommunalStateController.getCommunalViewShowing();
- }
- };
-
- final CommunalStateController.Callback mStateCallback = new CommunalStateController.Callback() {
- @Override
- public void onCommunalViewShowingChanged() {
- mExecutor.execute(() -> {
- mFilter.invalidateList();
- mNotificationEntryManager.updateNotifications("Communal mode state changed");
- });
- }
- };
-
- @Override
- public void attach(@NonNull NotifPipeline pipeline) {
- pipeline.addPreGroupFilter(mFilter);
- mCommunalStateController.addCallback(mStateCallback);
- if (!pipeline.isNewPipelineEnabled()) {
- mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor(
- entry -> mCommunalStateController.getCommunalViewShowing());
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 41b070635d4f..0df2162d3338 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -72,9 +72,9 @@ class HeadsUpCoordinator @Inject constructor(
private var mEndLifetimeExtension: OnEndLifetimeExtensionCallback? = null
private lateinit var mNotifPipeline: NotifPipeline
private var mNow: Long = -1
-
// notifs we've extended the lifetime for
private val mNotifsExtendingLifetime = ArraySet<NotificationEntry>()
+ private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
override fun attach(pipeline: NotifPipeline) {
mNotifPipeline = pipeline
@@ -101,10 +101,12 @@ class HeadsUpCoordinator @Inject constructor(
return
}
// Process all non-group adds/updates
- mPostedEntries.values.toList().forEach { posted ->
- if (!posted.entry.sbn.isGroup) {
- handlePostedEntry(posted, "non-group")
- mPostedEntries.remove(posted.key)
+ mHeadsUpManager.modifyHuns { hunMutator ->
+ mPostedEntries.values.toList().forEach { posted ->
+ if (!posted.entry.sbn.isGroup) {
+ handlePostedEntry(posted, hunMutator, "non-group")
+ mPostedEntries.remove(posted.key)
+ }
}
}
}
@@ -114,10 +116,10 @@ class HeadsUpCoordinator @Inject constructor(
* we know that stability and [NotifPromoter]s have been applied, so we can use the location of
* notifications in this list to determine what kind of group alert behavior should happen.
*/
- fun onBeforeFinalizeFilter(list: List<ListEntry>) {
+ fun onBeforeFinalizeFilter(list: List<ListEntry>) = mHeadsUpManager.modifyHuns { hunMutator ->
// Nothing to do if there are no other adds/updates
if (mPostedEntries.isEmpty()) {
- return
+ return@modifyHuns
}
// Calculate a bunch of information about the logical group and the locations of group
// entries in the nearly-finalized shade list. These may be used in the per-group loop.
@@ -138,13 +140,17 @@ class HeadsUpCoordinator @Inject constructor(
// If there is no logical summary, then there is no alert to transfer
if (logicalSummary == null) {
- postedEntries.forEach { handlePostedEntry(it, "logical-summary-missing") }
+ postedEntries.forEach {
+ handlePostedEntry(it, hunMutator, scenario = "logical-summary-missing")
+ }
return@forEach
}
// If summary isn't wanted to be heads up, then there is no alert to transfer
if (!isGoingToShowHunStrict(logicalSummary)) {
- postedEntries.forEach { handlePostedEntry(it, "logical-summary-not-alerting") }
+ postedEntries.forEach {
+ handlePostedEntry(it, hunMutator, scenario = "logical-summary-not-alerting")
+ }
return@forEach
}
@@ -177,7 +183,9 @@ class HeadsUpCoordinator @Inject constructor(
// If there is no child to receive the parent alert, then just handle the posted entries
// and return.
if (childToReceiveParentAlert == null) {
- postedEntries.forEach { handlePostedEntry(it, "no-transfer-target") }
+ postedEntries.forEach {
+ handlePostedEntry(it, hunMutator, scenario = "no-transfer-target")
+ }
return@forEach
}
@@ -189,51 +197,66 @@ class HeadsUpCoordinator @Inject constructor(
if (!isSummaryAttached) {
val summaryUpdateForRemoval = summaryUpdate?.also {
it.shouldHeadsUpEver = false
- } ?: PostedEntry(logicalSummary,
- wasAdded = false,
- wasUpdated = false,
- shouldHeadsUpEver = false,
- shouldHeadsUpAgain = false,
- isAlerting = mHeadsUpManager.isAlerting(logicalSummary.key),
- isBinding = isEntryBinding(logicalSummary),
+ } ?: PostedEntry(
+ logicalSummary,
+ wasAdded = false,
+ wasUpdated = false,
+ shouldHeadsUpEver = false,
+ shouldHeadsUpAgain = false,
+ isAlerting = mHeadsUpManager.isAlerting(logicalSummary.key),
+ isBinding = isEntryBinding(logicalSummary),
)
// If we transfer the alert and the summary isn't even attached, that means we
// should ensure the summary is no longer alerting, so we remove it here.
- handlePostedEntry(summaryUpdateForRemoval, "detached-summary-remove-alert")
- } else if (summaryUpdate!=null) {
- mLogger.logPostedEntryWillNotEvaluate(summaryUpdate, "attached-summary-transferred")
+ handlePostedEntry(
+ summaryUpdateForRemoval,
+ hunMutator,
+ scenario = "detached-summary-remove-alert")
+ } else if (summaryUpdate != null) {
+ mLogger.logPostedEntryWillNotEvaluate(
+ summaryUpdate,
+ reason = "attached-summary-transferred")
}
// Handle all posted entries -- if the child receiving the parent's alert is in the
// list, then set its flags to ensure it alerts.
var didAlertChildToReceiveParentAlert = false
postedEntries.asSequence()
- .filter { it.key != logicalSummary.key }
- .forEach { postedEntry ->
- if (childToReceiveParentAlert.key == postedEntry.key) {
- // Update the child's posted update so that it
- postedEntry.shouldHeadsUpEver = true
- postedEntry.shouldHeadsUpAgain = true
- handlePostedEntry(postedEntry, "child-alert-transfer-target-$targetType")
- didAlertChildToReceiveParentAlert = true
- } else {
- handlePostedEntry(postedEntry, "child-alert-non-target")
+ .filter { it.key != logicalSummary.key }
+ .forEach { postedEntry ->
+ if (childToReceiveParentAlert.key == postedEntry.key) {
+ // Update the child's posted update so that it
+ postedEntry.shouldHeadsUpEver = true
+ postedEntry.shouldHeadsUpAgain = true
+ handlePostedEntry(
+ postedEntry,
+ hunMutator,
+ scenario = "child-alert-transfer-target-$targetType")
+ didAlertChildToReceiveParentAlert = true
+ } else {
+ handlePostedEntry(
+ postedEntry,
+ hunMutator,
+ scenario = "child-alert-non-target")
+ }
}
- }
// If the child receiving the alert was not updated on this tick (which can happen in a
// standard alert transfer scenario), then construct an update so that we can apply it.
if (!didAlertChildToReceiveParentAlert) {
val posted = PostedEntry(
- childToReceiveParentAlert,
- wasAdded = false,
- wasUpdated = false,
- shouldHeadsUpEver = true,
- shouldHeadsUpAgain = true,
- isAlerting = mHeadsUpManager.isAlerting(childToReceiveParentAlert.key),
- isBinding = isEntryBinding(childToReceiveParentAlert),
+ childToReceiveParentAlert,
+ wasAdded = false,
+ wasUpdated = false,
+ shouldHeadsUpEver = true,
+ shouldHeadsUpAgain = true,
+ isAlerting = mHeadsUpManager.isAlerting(childToReceiveParentAlert.key),
+ isBinding = isEntryBinding(childToReceiveParentAlert),
)
- handlePostedEntry(posted, "non-posted-child-alert-transfer-target-$targetType")
+ handlePostedEntry(
+ posted,
+ hunMutator,
+ scenario = "non-posted-child-alert-transfer-target-$targetType")
}
}
// After this method runs, all posted entries should have been handled (or skipped).
@@ -292,9 +315,7 @@ class HeadsUpCoordinator @Inject constructor(
}
}
- private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
-
- fun handlePostedEntry(posted: PostedEntry, scenario: String) {
+ private fun handlePostedEntry(posted: PostedEntry, hunMutator: HunMutator, scenario: String) {
mLogger.logPostedEntryWillEvaluate(posted, scenario)
if (posted.wasAdded) {
if (posted.shouldHeadsUpEver) {
@@ -308,12 +329,12 @@ class HeadsUpCoordinator @Inject constructor(
// If alerting, we need to post an update. Otherwise we're still binding,
// and we can just let that finish.
if (posted.isAlerting) {
- mHeadsUpManager.updateNotification(posted.key, posted.shouldHeadsUpAgain)
+ hunMutator.updateNotification(posted.key, posted.shouldHeadsUpAgain)
}
} else {
if (posted.isAlerting) {
// We don't want this to be interrupting anymore, let's remove it
- mHeadsUpManager.removeNotification(posted.key, false /*removeImmediately*/)
+ hunMutator.removeNotification(posted.key, false /*removeImmediately*/)
} else {
// Don't let the bind finish
cancelHeadsUpBind(posted.entry)
@@ -366,7 +387,7 @@ class HeadsUpCoordinator @Inject constructor(
val shouldHeadsUpAgain = shouldHunAgain(entry)
val isAlerting = mHeadsUpManager.isAlerting(entry.key)
val isBinding = isEntryBinding(entry)
- mPostedEntries.compute(entry.key) { _, value ->
+ val posted = mPostedEntries.compute(entry.key) { _, value ->
value?.also { update ->
update.wasUpdated = true
update.shouldHeadsUpEver = update.shouldHeadsUpEver || shouldHeadsUpEver
@@ -383,6 +404,18 @@ class HeadsUpCoordinator @Inject constructor(
isBinding = isBinding,
)
}
+ // Handle cancelling alerts here, rather than in the OnBeforeFinalizeFilter, so that
+ // work can be done before the ShadeListBuilder is run. This prevents re-entrant
+ // behavior between this Coordinator, HeadsUpManager, and VisualStabilityManager.
+ if (posted?.shouldHeadsUpEver == false) {
+ if (posted.isAlerting) {
+ // We don't want this to be interrupting anymore, let's remove it
+ mHeadsUpManager.removeNotification(posted.key, false /*removeImmediately*/)
+ } else if (posted.isBinding) {
+ // Don't let the bind finish
+ cancelHeadsUpBind(posted.entry)
+ }
+ }
}
/**
@@ -543,3 +576,43 @@ private enum class GroupLocation { Detached, Isolated, Summary, Child }
private fun Map<String, GroupLocation>.getLocation(key: String): GroupLocation =
getOrDefault(key, GroupLocation.Detached)
+
+/**
+ * Invokes the given block with a [HunMutator] that defers all HUN removals. This ensures that the
+ * HeadsUpManager is notified of additions before removals, which prevents a glitch where the
+ * HeadsUpManager temporarily believes that nothing is alerting, causing bad re-entrant behavior.
+ */
+private fun <R> HeadsUpManager.modifyHuns(block: (HunMutator) -> R): R {
+ val mutator = HunMutatorImpl(this)
+ return block(mutator).also { mutator.commitModifications() }
+}
+
+/** Mutates the HeadsUp state of notifications. */
+private interface HunMutator {
+ fun updateNotification(key: String, alert: Boolean)
+ fun removeNotification(key: String, releaseImmediately: Boolean)
+}
+
+/**
+ * [HunMutator] implementation that defers removing notifications from the HeadsUpManager until
+ * after additions/updates.
+ */
+private class HunMutatorImpl(private val headsUpManager: HeadsUpManager) : HunMutator {
+ private val deferred = mutableListOf<Pair<String, Boolean>>()
+
+ override fun updateNotification(key: String, alert: Boolean) {
+ headsUpManager.updateNotification(key, alert)
+ }
+
+ override fun removeNotification(key: String, releaseImmediately: Boolean) {
+ val args = Pair(key, releaseImmediately)
+ deferred.add(args)
+ }
+
+ fun commitModifications() {
+ deferred.forEach { (key, releaseImmediately) ->
+ headsUpManager.removeNotification(key, releaseImmediately)
+ }
+ deferred.clear()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index 757fb5a2fe9a..985914acb2a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -45,7 +45,6 @@ class NotifCoordinatorsImpl @Inject constructor(
bubbleCoordinator: BubbleCoordinator,
headsUpCoordinator: HeadsUpCoordinator,
gutsCoordinator: GutsCoordinator,
- communalCoordinator: CommunalCoordinator,
conversationCoordinator: ConversationCoordinator,
debugModeCoordinator: DebugModeCoordinator,
groupCountCoordinator: GroupCountCoordinator,
@@ -58,7 +57,8 @@ class NotifCoordinatorsImpl @Inject constructor(
smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
viewConfigCoordinator: ViewConfigCoordinator,
visualStabilityCoordinator: VisualStabilityCoordinator,
- sensitiveContentCoordinator: SensitiveContentCoordinator
+ sensitiveContentCoordinator: SensitiveContentCoordinator,
+ activityLaunchAnimCoordinator: ActivityLaunchAnimCoordinator
) : NotifCoordinators {
private val mCoordinators: MutableList<Coordinator> = ArrayList()
@@ -86,7 +86,6 @@ class NotifCoordinatorsImpl @Inject constructor(
mCoordinators.add(appOpsCoordinator)
mCoordinators.add(deviceProvisionedCoordinator)
mCoordinators.add(bubbleCoordinator)
- mCoordinators.add(communalCoordinator)
mCoordinators.add(debugModeCoordinator)
mCoordinators.add(conversationCoordinator)
mCoordinators.add(groupCountCoordinator)
@@ -97,6 +96,7 @@ class NotifCoordinatorsImpl @Inject constructor(
mCoordinators.add(viewConfigCoordinator)
mCoordinators.add(visualStabilityCoordinator)
mCoordinators.add(sensitiveContentCoordinator)
+ mCoordinators.add(activityLaunchAnimCoordinator)
if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
mCoordinators.add(smartspaceDedupingCoordinator)
}
@@ -144,4 +144,4 @@ class NotifCoordinatorsImpl @Inject constructor(
companion object {
private const val TAG = "NotifCoordinators"
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index 72d091883ce6..3f8a39f62dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -34,11 +34,11 @@ import dagger.Binds
import dagger.Module
import javax.inject.Inject
-@Module(includes = [PrivateModule::class])
+@Module(includes = [PrivateSensitiveContentCoordinatorModule::class])
interface SensitiveContentCoordinatorModule
@Module
-private interface PrivateModule {
+private interface PrivateSensitiveContentCoordinatorModule {
@Binds
fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator
}
@@ -121,4 +121,4 @@ private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<Noti
if (listEntry is GroupEntry) {
yieldAll(extractAllRepresentativeEntries(listEntry.children))
}
- } \ No newline at end of file
+ }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index 3aa3549a7c27..699c4e77321e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -32,7 +32,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
+import com.android.systemui.statusbar.phone.NotifPanelEvents;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -53,10 +53,10 @@ import javax.inject.Inject;
// TODO(b/204468557): Move to @CoordinatorScope
@SysUISingleton
public class VisualStabilityCoordinator implements Coordinator, Dumpable,
- NotifPanelEventSource.Callbacks {
+ NotifPanelEvents.Listener {
private final DelayableExecutor mDelayableExecutor;
private final HeadsUpManager mHeadsUpManager;
- private final NotifPanelEventSource mNotifPanelEventSource;
+ private final NotifPanelEvents mNotifPanelEvents;
private final StatusBarStateController mStatusBarStateController;
private final VisualStabilityProvider mVisualStabilityProvider;
private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -87,7 +87,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable,
DelayableExecutor delayableExecutor,
DumpManager dumpManager,
HeadsUpManager headsUpManager,
- NotifPanelEventSource notifPanelEventSource,
+ NotifPanelEvents notifPanelEvents,
StatusBarStateController statusBarStateController,
VisualStabilityProvider visualStabilityProvider,
WakefulnessLifecycle wakefulnessLifecycle) {
@@ -96,7 +96,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable,
mWakefulnessLifecycle = wakefulnessLifecycle;
mStatusBarStateController = statusBarStateController;
mDelayableExecutor = delayableExecutor;
- mNotifPanelEventSource = notifPanelEventSource;
+ mNotifPanelEvents = notifPanelEvents;
dumpManager.registerDumpable(this);
}
@@ -109,7 +109,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable,
mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
mPulsing = mStatusBarStateController.isPulsing();
- mNotifPanelEventSource.registerCallbacks(this);
+ mNotifPanelEvents.registerListener(this);
pipeline.setVisualStabilityManager(mNotifStabilityManager);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
index a26d50d2a059..274affd9da43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator.dagger
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.coordinator.ActivityLaunchAnimCoordinatorModule
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
@@ -47,7 +48,10 @@ interface CoordinatorsSubcomponent {
}
}
-@Module(includes = [SensitiveContentCoordinatorModule::class])
+@Module(includes = [
+ ActivityLaunchAnimCoordinatorModule::class,
+ SensitiveContentCoordinatorModule::class,
+])
private abstract class InternalCoordinatorsModule {
@Binds
@Internal
@@ -62,4 +66,4 @@ private annotation class Internal
@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
-annotation class CoordinatorScope \ No newline at end of file
+annotation class CoordinatorScope
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt
deleted file mode 100644
index 470737e3b772..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.statusbar.notification.collection.render
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
-import com.android.systemui.util.ListenerSet
-import dagger.Binds
-import dagger.Module
-import dagger.Provides
-import dagger.multibindings.IntoSet
-
-/** Provides certain notification panel events. */
-interface NotifPanelEventSource {
-
- /** Registers callbacks to be invoked when notification panel events occur. */
- fun registerCallbacks(callbacks: Callbacks)
-
- /** Unregisters callbacks previously registered via [.registerCallbacks] */
- fun unregisterCallbacks(callbacks: Callbacks)
-
- /** Callbacks for certain notification panel events. */
- interface Callbacks {
-
- /** Invoked when the notification panel starts or stops collapsing. */
- fun onPanelCollapsingChanged(isCollapsing: Boolean)
-
- /**
- * Invoked when the notification panel starts or stops launching an [android.app.Activity].
- */
- fun onLaunchingActivityChanged(isLaunchingActivity: Boolean)
- }
-}
-
-@Module
-abstract class NotifPanelEventSourceModule {
-
- @Binds
- @SysUISingleton
- abstract fun bindEventSource(manager: NotifPanelEventSourceManager): NotifPanelEventSource
-
- @Module
- companion object {
- @JvmStatic
- @Provides
- fun provideManager(): NotifPanelEventSourceManager = NotifPanelEventSourceManagerImpl()
- }
-}
-
-@Module
-object StatusBarNotifPanelEventSourceModule {
- @JvmStatic
- @Provides
- @IntoSet
- @CentralSurfacesScope
- fun bindStartable(
- manager: NotifPanelEventSourceManager,
- notifPanelController: NotificationPanelViewController
- ): CentralSurfacesComponent.Startable =
- EventSourceStatusBarStartableImpl(manager, notifPanelController)
-}
-
-/**
- * Management layer that bridges [SysUiSingleton] and [CentralSurfacesScope]. Necessary because code
- * that wants to listen to [NotifPanelEventSource] lives in [SysUiSingleton], but the events
- * themselves come from [NotificationPanelViewController] in [CentralSurfacesScope].
- */
-interface NotifPanelEventSourceManager : NotifPanelEventSource {
- var eventSource: NotifPanelEventSource?
-}
-
-private class NotifPanelEventSourceManagerImpl
- : NotifPanelEventSourceManager, NotifPanelEventSource.Callbacks {
-
- private val callbackSet = ListenerSet<NotifPanelEventSource.Callbacks>()
-
- override var eventSource: NotifPanelEventSource? = null
- set(value) {
- field?.unregisterCallbacks(this)
- value?.registerCallbacks(this)
- field = value
- }
-
- override fun registerCallbacks(callbacks: NotifPanelEventSource.Callbacks) {
- callbackSet.addIfAbsent(callbacks)
- }
-
- override fun unregisterCallbacks(callbacks: NotifPanelEventSource.Callbacks) {
- callbackSet.remove(callbacks)
- }
-
- override fun onPanelCollapsingChanged(isCollapsing: Boolean) {
- callbackSet.forEach { it.onPanelCollapsingChanged(isCollapsing) }
- }
-
- override fun onLaunchingActivityChanged(isLaunchingActivity: Boolean) {
- callbackSet.forEach { it.onLaunchingActivityChanged(isLaunchingActivity) }
- }
-}
-
-private class EventSourceStatusBarStartableImpl(
- private val manager: NotifPanelEventSourceManager,
- private val notifPanelController: NotificationPanelViewController
-) : CentralSurfacesComponent.Startable {
-
- override fun start() {
- manager.eventSource = notifPanelController
- }
-
- override fun stop() {
- manager.eventSource = null
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 51bbf1c80478..efe88e6d4f0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -68,7 +68,6 @@ import com.android.systemui.statusbar.notification.collection.render.GroupExpans
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSourceModule;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -84,9 +83,11 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEventsModule;
+import com.android.systemui.statusbar.phone.NotifPanelEventsModule;
import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.wmshell.BubblesManager;
@@ -106,8 +107,9 @@ import dagger.Provides;
*/
@Module(includes = {
CoordinatorsModule.class,
+ NotifActivityLaunchEventsModule.class,
NotifPipelineChoreographerModule.class,
- NotifPanelEventSourceModule.class,
+ NotifPanelEventsModule.class,
NotificationSectionHeadersModule.class,
})
public interface NotificationsModule {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index f40a3c7186e6..3b22f2a86bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -102,6 +102,16 @@ public class AmbientState {
/** Whether we are swiping up. */
private boolean mIsSwipingUp;
+ /** Whether we are flinging the shade open or closed. */
+ private boolean mIsFlinging;
+
+ /**
+ * Whether we need to do a fling down after swiping up on lockscreen.
+ * True right after we swipe up on lockscreen and have not finished the fling down that follows.
+ * False when we stop flinging or leave lockscreen.
+ */
+ private boolean mNeedFlingAfterLockscreenSwipeUp = false;
+
/**
* @return Height of the notifications panel without top padding when expansion completes.
*/
@@ -142,6 +152,10 @@ public class AmbientState {
* @param isSwipingUp Whether we are swiping up.
*/
public void setSwipingUp(boolean isSwipingUp) {
+ if (!isSwipingUp && mIsSwipingUp) {
+ // Just stopped swiping up.
+ mNeedFlingAfterLockscreenSwipeUp = true;
+ }
mIsSwipingUp = isSwipingUp;
}
@@ -153,6 +167,17 @@ public class AmbientState {
}
/**
+ * @param isFlinging Whether we are flinging the shade open or closed.
+ */
+ public void setIsFlinging(boolean isFlinging) {
+ if (isOnKeyguard() && !isFlinging && mIsFlinging) {
+ // Just stopped flinging.
+ mNeedFlingAfterLockscreenSwipeUp = false;
+ }
+ mIsFlinging = isFlinging;
+ }
+
+ /**
* @return Fraction of shade expansion.
*/
public float getExpansionFraction() {
@@ -459,6 +484,9 @@ public class AmbientState {
}
public void setStatusBarState(int statusBarState) {
+ if (mStatusBarState != StatusBarState.KEYGUARD) {
+ mNeedFlingAfterLockscreenSwipeUp = false;
+ }
mStatusBarState = statusBarState;
}
@@ -522,6 +550,13 @@ public class AmbientState {
}
/**
+ * @return Whether we need to do a fling down after swiping up on lockscreen.
+ */
+ public boolean isFlingingAfterSwipeUpOnLockscreen() {
+ return mIsFlinging && mNeedFlingAfterLockscreenSwipeUp;
+ }
+
+ /**
* @return whether a view is dozing and not pulsing right now
*/
public boolean isDozingAndNotPulsing(ExpandableView view) {
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 efe559a64cc4..5b9dbd0f3361 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
@@ -202,9 +202,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private float mQsExpansionFraction;
private final int mSplitShadeMinContentHeight;
- /** Whether we are flinging the shade open or closed. */
- private boolean mIsFlinging;
-
/**
* The algorithm which calculates the properties for our children
*/
@@ -407,7 +404,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
*/
private float mBackgroundXFactor = 1f;
- private boolean mQsExpanded;
+ /**
+ * Indicates QS are full screen and pushing notifications out of the screen.
+ * It's different from QS just being expanded as in split shade QS can be expanded and
+ * still don't take full screen nor influence notifications.
+ */
+ private boolean mQsFullScreen;
private boolean mForwardScrollable;
private boolean mBackwardScrollable;
private NotificationShelf mShelf;
@@ -1133,7 +1135,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
private void updateAlgorithmLayoutMinHeight() {
- mAmbientState.setLayoutMinHeight(mQsExpanded || isHeadsUpTransition()
+ mAmbientState.setLayoutMinHeight(mQsFullScreen || isHeadsUpTransition()
? getLayoutMinHeight() : 0);
}
@@ -1263,13 +1265,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
/**
- * @return Whether we should skip stack height update for lockscreen swipe-up or unlock hint.
+ * @return Whether we should skip stack height updates.
+ * True when
+ * 1) Unlock hint is running
+ * 2) Swiping up on lockscreen or flinging down after swipe up
*/
private boolean shouldSkipHeightUpdate() {
- // After the user swipes up on lockscreen and lets go,
- // {@link PanelViewController) flings the shade back down.
- return mAmbientState.isOnKeyguard() && (
- mAmbientState.isUnlockHintRunning() || mAmbientState.isSwipingUp() || mIsFlinging);
+ return mAmbientState.isOnKeyguard()
+ && (mAmbientState.isUnlockHintRunning()
+ || mAmbientState.isSwipingUp()
+ || mAmbientState.isFlingingAfterSwipeUpOnLockscreen());
}
/**
@@ -1361,7 +1366,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
translationY = 0;
if (mShouldShowShelfOnly) {
stackHeight = mTopPadding + mShelf.getIntrinsicHeight();
- } else if (mQsExpanded) {
+ } else if (mQsFullScreen) {
int stackStartPosition = mContentHeight - mTopPadding + mIntrinsicPadding;
int stackEndPosition = mMaxTopPadding + mShelf.getIntrinsicHeight();
if (stackStartPosition <= stackEndPosition) {
@@ -2318,7 +2323,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateScrollability() {
- boolean scrollable = !mQsExpanded && getScrollRange() > 0;
+ boolean scrollable = !mQsFullScreen && getScrollRange() > 0;
if (scrollable != mScrollable) {
mScrollable = scrollable;
setFocusable(scrollable);
@@ -4839,14 +4844,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setQsExpanded(boolean qsExpanded) {
- mQsExpanded = qsExpanded;
+ public void setQsFullScreen(boolean qsFullScreen) {
+ mQsFullScreen = qsFullScreen;
updateAlgorithmLayoutMinHeight();
updateScrollability();
}
- boolean isQsExpanded() {
- return mQsExpanded;
+ boolean isQsFullScreen() {
+ return mQsFullScreen;
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5009,13 +5014,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAmbientState.setUnlockHintRunning(running);
}
- /**
- * @param isFlinging Whether we are flinging the shade open or closed.
- */
- public void setIsFlinging(boolean isFlinging) {
- mIsFlinging = isFlinging;
- }
-
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setHeadsUpGoingAwayAnimationsAllowed(boolean headsUpGoingAwayAnimationsAllowed) {
mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed;
@@ -5814,10 +5812,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSwipeHelper.resetExposedMenuView(animate, force);
}
- boolean isUsingSplitNotificationShade() {
- return mShouldUseSplitNotificationShade;
- }
-
static boolean matchesSelection(
ExpandableNotificationRow row,
@SelectedRows int selection) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index df6b8f59fc36..7df8e7df486e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -111,13 +111,13 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationSnooze;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -1086,8 +1086,8 @@ public class NotificationStackScrollLayoutController {
}
}
- public void setQsExpanded(boolean expanded) {
- mView.setQsExpanded(expanded);
+ public void setQsFullScreen(boolean fullScreen) {
+ mView.setQsFullScreen(fullScreen);
updateShowEmptyShadeView();
}
@@ -1181,13 +1181,6 @@ public class NotificationStackScrollLayoutController {
mView.setUnlockHintRunning(running);
}
- /**
- * @param isFlinging Whether we are flinging the shade open or close.
- */
- public void setIsFlinging(boolean isFlinging) {
- mView.setIsFlinging(isFlinging);
- }
-
public boolean isFooterViewNotGone() {
return mView.isFooterViewNotGone();
}
@@ -1211,7 +1204,7 @@ public class NotificationStackScrollLayoutController {
public void updateShowEmptyShadeView() {
Trace.beginSection("NSSLC.updateShowEmptyShadeView");
mShowEmptyShadeView = mBarState != KEYGUARD
- && (!mView.isQsExpanded() || mView.isUsingSplitNotificationShade())
+ && !mView.isQsFullScreen()
&& getVisibleNotificationCount() == 0;
mView.updateEmptyShadeView(
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 fe637c14ee33..4bf944ae13c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -20,6 +20,8 @@ import static android.app.StatusBarManager.SESSION_KEYGUARD;
import android.annotation.IntDef;
import android.content.res.Resources;
+import android.hardware.biometrics.BiometricFaceConstants;
+import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.fingerprint.FingerprintManager;
import android.metrics.LogMaker;
@@ -344,7 +346,15 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
}
@Override
- public void onBiometricAcquired(BiometricSourceType biometricSourceType) {
+ public void onBiometricAcquired(BiometricSourceType biometricSourceType,
+ int acquireInfo) {
+ if (BiometricSourceType.FINGERPRINT == biometricSourceType
+ && acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
+ return;
+ } else if (BiometricSourceType.FACE == biometricSourceType
+ && acquireInfo != BiometricFaceConstants.FACE_ACQUIRED_GOOD) {
+ return;
+ }
Trace.beginSection("BiometricUnlockController#onBiometricAcquired");
releaseBiometricWakeLock();
if (isWakeAndUnlock()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index cc16ce2f92e6..84adc5679a81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -1505,7 +1505,7 @@ public class CentralSurfaces extends CoreStartable implements
return (v, event) -> {
mAutoHideController.checkUserAutoHide(event);
mRemoteInputManager.checkRemoteInputOutside(event);
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
if (mExpandedVisible) {
mShadeController.animateCollapsePanels();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 541aeab22a80..dc1af362ec23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -32,7 +32,6 @@ import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.admin.DevicePolicyManager;
-import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -1109,8 +1108,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
Intent intent = mQRCodeScannerController.getIntent();
if (intent != null) {
try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
+ ActivityTaskManager.getService().startActivityAsUser(
+ null, getContext().getBasePackageName(),
+ getContext().getAttributionTag(), intent,
+ intent.resolveTypeIfNeeded(getContext().getContentResolver()),
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
+ UserHandle.CURRENT.getIdentifier());
+ } catch (RemoteException e) {
// This is unexpected. Nonetheless, just log the error and prevent the UI from
// crashing
Log.e(TAG, "Unexpected intent: " + intent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
index 868efa027f40..02b235493715 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
@@ -44,7 +44,7 @@ class LSShadeTransitionLogger @Inject constructor(
fun logDragDownAborted() {
buffer.log(TAG, LogLevel.INFO, {}, {
- "The drag down was reset"
+ "The drag down was aborted and reset to 0f."
})
}
@@ -82,6 +82,12 @@ class LSShadeTransitionLogger @Inject constructor(
LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_PULL_SHADE_OPEN)
}
+ fun logDragDownAmountReset() {
+ buffer.log(TAG, LogLevel.DEBUG, {}, {
+ "The drag down amount has been reset to 0f."
+ })
+ }
+
fun logDefaultGoToFullShadeAnimation(delay: Long) {
buffer.log(TAG, LogLevel.DEBUG, {
long1 = delay
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt
new file mode 100644
index 000000000000..f46d07338206
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt
@@ -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.systemui.statusbar.phone
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+
+/** Provides events about [android.app.Activity] launches from Notifications. */
+interface NotifActivityLaunchEvents {
+
+ /** Registers a [Listener] to be invoked when notification activity launch events occur. */
+ fun registerListener(listener: Listener)
+
+ /** Unregisters a [Listener] previously registered via [registerListener] */
+ fun unregisterListener(listener: Listener)
+
+ /** Listener for events about [android.app.Activity] launches from Notifications. */
+ interface Listener {
+
+ /** Invoked when an activity has started launching from a notification. */
+ fun onStartLaunchNotifActivity(entry: NotificationEntry)
+
+ /** Invoked when an activity has finished launching. */
+ fun onFinishLaunchNotifActivity(entry: NotificationEntry)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java
new file mode 100644
index 000000000000..84ff538677b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Binds;
+import dagger.Module;
+
+/** Provides a {@link NotifActivityLaunchEvents} in {@link SysUISingleton} scope. */
+@Module
+public abstract class NotifActivityLaunchEventsModule {
+ @Binds
+ abstract NotifActivityLaunchEvents bindLaunchEvents(
+ StatusBarNotificationActivityStarter.LaunchEventsEmitter impl);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
new file mode 100644
index 000000000000..a385e22c1aff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
@@ -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.systemui.statusbar.phone
+
+/** Provides certain notification panel events. */
+interface NotifPanelEvents {
+
+ /** Registers callbacks to be invoked when notification panel events occur. */
+ fun registerListener(listener: Listener)
+
+ /** Unregisters callbacks previously registered via [registerListener] */
+ fun unregisterListener(listener: Listener)
+
+ /** Callbacks for certain notification panel events. */
+ interface Listener {
+
+ /** Invoked when the notification panel starts or stops collapsing. */
+ fun onPanelCollapsingChanged(isCollapsing: Boolean)
+
+ /**
+ * Invoked when the notification panel starts or stops launching an [android.app.Activity].
+ */
+ fun onLaunchingActivityChanged(isLaunchingActivity: Boolean)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
index 9621e5f5f1a0..2aaf6a5f4391 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 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,13 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.tv;
+package com.android.systemui.statusbar.phone;
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Binds;
import dagger.Module;
-/**
- * Dagger module for including the SysUIComponent.
- */
-@Module(subcomponents = {TvSysUIComponent.class})
-public abstract class TvSysUIComponentModule {
+/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
+@Module
+public abstract class NotifPanelEventsModule {
+ @Binds
+ abstract NotifPanelEvents bindPanelEvents(
+ NotificationPanelViewController.PanelEventsEmitter impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 01860a822503..cc8a70388ed0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -120,14 +120,8 @@ import com.android.systemui.animation.LaunchAnimator;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-import com.android.systemui.communal.CommunalHostViewPositionAlgorithm;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.CommunalSourceMonitor;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.communal.dagger.CommunalViewComponent;
import com.android.systemui.controls.dagger.ControlsComponent;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
@@ -176,7 +170,6 @@ import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -209,7 +202,6 @@ import com.android.wm.shell.animation.FlingAnimationUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -223,8 +215,7 @@ import javax.inject.Inject;
import javax.inject.Provider;
@CentralSurfacesComponent.CentralSurfacesScope
-public class NotificationPanelViewController extends PanelViewController
- implements NotifPanelEventSource {
+public class NotificationPanelViewController extends PanelViewController {
private static final boolean DEBUG = false;
@@ -309,13 +300,10 @@ public class NotificationPanelViewController extends PanelViewController
private final PulseExpansionHandler mPulseExpansionHandler;
private final KeyguardBypassController mKeyguardBypassController;
private final KeyguardUpdateMonitor mUpdateMonitor;
- private final CommunalSourceMonitor mCommunalSourceMonitor;
- private final CommunalStateController mCommunalStateController;
private final ConversationNotificationManager mConversationNotificationManager;
private final AuthController mAuthController;
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- private final CommunalViewComponent.Factory mCommunalViewComponentFactory;
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@@ -335,6 +323,7 @@ public class NotificationPanelViewController extends PanelViewController
private final TapAgainViewController mTapAgainViewController;
private final SplitShadeHeaderController mSplitShadeHeaderController;
private final RecordingController mRecordingController;
+ private final PanelEventsEmitter mPanelEventsEmitter;
private boolean mShouldUseSplitNotificationShade;
// The bottom padding reserved for elements of the keyguard measuring notifications
private float mKeyguardNotificationBottomPadding;
@@ -350,8 +339,6 @@ public class NotificationPanelViewController extends PanelViewController
@VisibleForTesting QS mQs;
private FrameLayout mQsFrame;
private QsFrameTranslateController mQsFrameTranslateController;
- @Nullable
- private CommunalHostViewController mCommunalViewController;
private KeyguardStatusViewController mKeyguardStatusViewController;
private LockIconViewController mLockIconViewController;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -364,8 +351,6 @@ public class NotificationPanelViewController extends PanelViewController
private VelocityTracker mQsVelocityTracker;
private boolean mQsTracking;
- private CommunalHostView mCommunalView;
-
/**
* If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
* the expansion for quick settings.
@@ -373,6 +358,12 @@ public class NotificationPanelViewController extends PanelViewController
private boolean mConflictingQsExpansionGesture;
private boolean mPanelExpanded;
+
+ /**
+ * Indicates that QS is in expanded state which can happen by:
+ * - single pane shade: expanding shade and then expanding QS
+ * - split shade: just expanding shade (QS are expanded automatically)
+ */
private boolean mQsExpanded;
private boolean mQsExpandedWhenExpandingStarted;
private boolean mQsFullyExpanded;
@@ -413,16 +404,14 @@ public class NotificationPanelViewController extends PanelViewController
private final KeyguardClockPositionAlgorithm.Result
mClockPositionResult =
new KeyguardClockPositionAlgorithm.Result();
- private final CommunalHostViewPositionAlgorithm
- mCommunalPositionAlgorithm =
- new CommunalHostViewPositionAlgorithm();
- private final CommunalHostViewPositionAlgorithm.Result
- mCommunalPositionResult =
- new CommunalHostViewPositionAlgorithm.Result();
private boolean mIsExpanding;
private boolean mBlockTouches;
- // Used for two finger gesture as well as accessibility shortcut to QS.
+
+ /**
+ * Determines if QS should be already expanded when expanding shade.
+ * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
+ */
private boolean mQsExpandImmediate;
private boolean mTwoFingerQsExpandPossible;
private String mHeaderDebugInfo;
@@ -523,10 +512,6 @@ public class NotificationPanelViewController extends PanelViewController
mPanelAlphaAnimator.getProperty(), Interpolators.ALPHA_IN);
private final NotificationEntryManager mEntryManager;
- private final CommunalSourceMonitor.Callback mCommunalSourceMonitorCallback;
-
- private WeakReference<CommunalSource> mCommunalSource;
-
private final CommandQueue mCommandQueue;
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final UserManager mUserManager;
@@ -664,8 +649,6 @@ public class NotificationPanelViewController extends PanelViewController
private Optional<NotificationPanelUnfoldAnimationController>
mNotificationPanelUnfoldAnimationController;
- private final ListenerSet<Callbacks> mNotifEventSourceCallbacks = new ListenerSet<>();
-
private final NotificationListContainer mNotificationListContainer;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -688,32 +671,6 @@ public class NotificationPanelViewController extends PanelViewController
}
};
- private final CommunalStateController.Callback mCommunalStateCallback =
- new CommunalStateController.Callback() {
- @Override
- public void onCommunalViewShowingChanged() {
- mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
- mBarState,
- mKeyguardStateController.isKeyguardFadingAway(),
- mStatusBarStateController.goingToFullShade(),
- mBarState);
- if (mKeyguardUserSwitcherController != null) {
- mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
- mBarState,
- mKeyguardStateController.isKeyguardFadingAway(),
- mStatusBarStateController.goingToFullShade(),
- mBarState);
- }
- if (mKeyguardQsUserSwitchController != null) {
- mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
- mBarState,
- mKeyguardStateController.isKeyguardFadingAway(),
- mStatusBarStateController.goingToFullShade(),
- mBarState);
- }
- }
- };
-
private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
@Override
public void onDoubleTapRequired() {
@@ -739,7 +696,6 @@ public class NotificationPanelViewController extends PanelViewController
FalsingCollector falsingCollector,
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotificationEntryManager notificationEntryManager,
- CommunalStateController communalStateController,
KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController,
StatusBarWindowStateController statusBarWindowStateController,
@@ -749,7 +705,7 @@ public class NotificationPanelViewController extends PanelViewController
LatencyTracker latencyTracker, PowerManager powerManager,
AccessibilityManager accessibilityManager, @DisplayId int displayId,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- CommunalSourceMonitor communalSourceMonitor, MetricsLogger metricsLogger,
+ MetricsLogger metricsLogger,
ActivityManager activityManager,
ConfigurationController configurationController,
Provider<FlingAnimationUtils.Builder> flingAnimationUtilsBuilder,
@@ -763,7 +719,6 @@ public class NotificationPanelViewController extends PanelViewController
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
- CommunalViewComponent.Factory communalViewComponentFactory,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
NotificationGroupManagerLegacy groupManager,
NotificationIconAreaController notificationIconAreaController,
@@ -796,7 +751,8 @@ public class NotificationPanelViewController extends PanelViewController
QsFrameTranslateController qsFrameTranslateController,
SysUiState sysUiState,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- NotificationListContainer notificationListContainer) {
+ NotificationListContainer notificationListContainer,
+ PanelEventsEmitter panelEventsEmitter) {
super(view,
falsingManager,
dozeLog,
@@ -832,8 +788,6 @@ public class NotificationPanelViewController extends PanelViewController
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mGroupManager = groupManager;
mNotificationIconAreaController = notificationIconAreaController;
- mCommunalStateController = communalStateController;
- mCommunalViewComponentFactory = communalViewComponentFactory;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
mDepthController = notificationShadeDepthController;
@@ -868,6 +822,7 @@ public class NotificationPanelViewController extends PanelViewController
mSecureSettings = secureSettings;
mInteractionJankMonitor = interactionJankMonitor;
mSysUiState = sysUiState;
+ mPanelEventsEmitter = panelEventsEmitter;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
if (mQs != null) {
mQs.animateHeaderSlidingOut();
@@ -877,7 +832,6 @@ public class NotificationPanelViewController extends PanelViewController
mThemeResId = mView.getContext().getThemeResId();
mKeyguardBypassController = bypassController;
mUpdateMonitor = keyguardUpdateMonitor;
- mCommunalSourceMonitor = communalSourceMonitor;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
lockscreenShadeTransitionController.setNotificationPanelController(this);
DynamicPrivacyControlListener
@@ -924,9 +878,6 @@ public class NotificationPanelViewController extends PanelViewController
mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
- mCommunalSourceMonitorCallback = (source) -> {
- mUiExecutor.execute(() -> setCommunalSource(source));
- };
mQsFrameTranslateController = qsFrameTranslateController;
updateUserSwitcherFlags();
onFinishInflate();
@@ -962,7 +913,6 @@ public class NotificationPanelViewController extends PanelViewController
private void onFinishInflate() {
loadDimens();
mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
- mCommunalView = mView.findViewById(R.id.communal_host);
FrameLayout userAvatarContainer = null;
KeyguardUserSwitcherView keyguardUserSwitcherView = null;
@@ -984,20 +934,11 @@ public class NotificationPanelViewController extends PanelViewController
.getKeyguardStatusBarViewController();
mKeyguardStatusBarViewController.init();
- if (mCommunalView != null) {
- CommunalViewComponent communalViewComponent =
- mCommunalViewComponentFactory.build(mCommunalView);
- mCommunalViewController =
- communalViewComponent.getCommunalHostViewController();
- mCommunalViewController.init();
- }
-
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
updateViewControllers(
mView.findViewById(R.id.keyguard_status_view),
userAvatarContainer,
- keyguardUserSwitcherView,
- mCommunalView);
+ keyguardUserSwitcherView);
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
R.id.notification_stack_scroller);
@@ -1088,8 +1029,7 @@ public class NotificationPanelViewController extends PanelViewController
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
FrameLayout userAvatarView,
- KeyguardUserSwitcherView keyguardUserSwitcherView,
- CommunalHostView communalView) {
+ KeyguardUserSwitcherView keyguardUserSwitcherView) {
// Re-associate the KeyguardStatusViewController
KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
@@ -1282,7 +1222,7 @@ public class NotificationPanelViewController extends PanelViewController
showKeyguardUserSwitcher /* enabled */);
updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
- keyguardUserSwitcherView, mCommunalView);
+ keyguardUserSwitcherView);
// Update keyguard bottom area
int index = mView.indexOfChild(mKeyguardBottomArea);
@@ -1428,10 +1368,6 @@ public class NotificationPanelViewController extends PanelViewController
int stackScrollerPadding;
boolean onKeyguard = isOnKeyguard();
- if (onKeyguard) {
- updateCommunalViewAppearance();
- }
-
if (onKeyguard || forceClockUpdate) {
updateClockAppearance();
}
@@ -1457,22 +1393,6 @@ public class NotificationPanelViewController extends PanelViewController
mAnimateNextPositionUpdate = false;
}
- private void updateCommunalViewAppearance() {
- if (mCommunalViewController == null) {
- return;
- }
-
- float expandedFraction =
- mScreenOffAnimationController.shouldExpandNotifications()
- ? 1.0f : getExpandedFraction();
- mCommunalPositionAlgorithm.setup(expandedFraction, mCommunalView.getHeight());
- mCommunalPositionAlgorithm.run(mCommunalPositionResult);
- boolean animate =
- mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending()
- || mAnimateNextPositionUpdate;
- mCommunalViewController.updatePosition(mCommunalPositionResult.communalY, animate);
- }
-
private void updateClockAppearance() {
int userSwitcherPreferredY = mStatusBarHeaderHeightKeyguard;
boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
@@ -1547,9 +1467,8 @@ public class NotificationPanelViewController extends PanelViewController
private void updateKeyguardStatusViewAlignment(boolean animate) {
boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
.getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
- boolean hasCommunalSurface = mCommunalSource != null && mCommunalSource.get() != null;
- boolean shouldBeCentered = !mShouldUseSplitNotificationShade
- || (!hasVisibleNotifications && !hasCommunalSurface) || mDozing;
+ boolean shouldBeCentered = !mShouldUseSplitNotificationShade || !hasVisibleNotifications
+ || mDozing;
if (mStatusViewCentered != shouldBeCentered) {
mStatusViewCentered = shouldBeCentered;
ConstraintSet constraintSet = new ConstraintSet();
@@ -1558,6 +1477,11 @@ public class NotificationPanelViewController extends PanelViewController
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (animate) {
ChangeBounds transition = new ChangeBounds();
+ if (mShouldUseSplitNotificationShade) {
+ // Excluding media from the transition on split-shade, as it doesn't transition
+ // horizontally properly.
+ transition.excludeTarget(R.id.status_view_media_container, true);
+ }
transition.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
transition.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
TransitionManager.beginDelayedTransition(mNotificationContainerParent, transition);
@@ -1579,11 +1503,6 @@ public class NotificationPanelViewController extends PanelViewController
* @return the maximum keyguard notifications that can fit on the screen
*/
private int computeMaxKeyguardNotifications() {
- // Do not show any notifications on the keyguard if a communal source is set.
- if (mCommunalSource != null && mCommunalSource.get() != null) {
- return 0;
- }
-
float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding();
int notificationPadding = Math.max(
1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
@@ -1707,12 +1626,6 @@ public class NotificationPanelViewController extends PanelViewController
return true;
}
- private void updateCommunal() {
- if (mCommunalViewController != null) {
- mCommunalViewController.setAlpha(mKeyguardOnlyContentAlpha);
- }
- }
-
private void updateClock() {
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
mKeyguardStatusViewController.setAlpha(alpha);
@@ -1786,11 +1699,16 @@ public class NotificationPanelViewController extends PanelViewController
if (mQsExpanded) {
mQsExpandImmediate = true;
- mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+ setShowShelfOnly(true);
}
super.collapse(delayed, speedUpFactor);
}
+ private void setShowShelfOnly(boolean shelfOnly) {
+ mNotificationStackScrollLayoutController.setShouldShowShelfOnly(
+ shelfOnly && !mShouldUseSplitNotificationShade);
+ }
+
public void closeQs() {
cancelQsAnimation();
setQsExpansion(mQsMinExpansionHeight);
@@ -1827,7 +1745,7 @@ public class NotificationPanelViewController extends PanelViewController
public void expandWithQs() {
if (isQsExpansionEnabled()) {
mQsExpandImmediate = true;
- mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+ setShowShelfOnly(true);
}
if (isFullyCollapsed()) {
expand(true /* animate */);
@@ -1860,14 +1778,14 @@ public class NotificationPanelViewController extends PanelViewController
mHeadsUpTouchHelper.notifyFling(!expand);
mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
- mNotificationStackScrollLayoutController.setIsFlinging(true);
+ mAmbientState.setIsFlinging(true);
super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
}
@Override
protected void onFlingEnd(boolean cancelled) {
super.onFlingEnd(cancelled);
- mNotificationStackScrollLayoutController.setIsFlinging(false);
+ mAmbientState.setIsFlinging(false);
}
private boolean onQsIntercept(MotionEvent event) {
@@ -2026,7 +1944,15 @@ public class NotificationPanelViewController extends PanelViewController
mFalsingManager.isFalseTouch(QS_COLLAPSE);
}
- flingSettings(vel, expandsQs && !isCancelMotionEvent ? FLING_EXPAND : FLING_COLLAPSE);
+ int flingType;
+ if (expandsQs && !isCancelMotionEvent) {
+ flingType = FLING_EXPAND;
+ } else if (mShouldUseSplitNotificationShade) {
+ flingType = FLING_HIDE;
+ } else {
+ flingType = FLING_COLLAPSE;
+ }
+ flingSettings(vel, flingType);
}
private void logQsSwipeDown(float y) {
@@ -2091,8 +2017,10 @@ public class NotificationPanelViewController extends PanelViewController
return false;
}
final int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
- && mBarState != KEYGUARD && !mQsExpanded && isQsExpansionEnabled()) {
+ boolean collapsedQs = !mQsExpanded && !mShouldUseSplitNotificationShade;
+ boolean expandedShadeCollapsedQs = getExpandedFraction() == 1f && mBarState != KEYGUARD
+ && collapsedQs && isQsExpansionEnabled();
+ if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) {
// Down in the empty area while fully expanded - go to QS.
mQsTracking = true;
traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -2107,7 +2035,7 @@ public class NotificationPanelViewController extends PanelViewController
}
if (!mQsExpandImmediate && mQsTracking) {
onQsTouch(event);
- if (!mConflictingQsExpansionGesture) {
+ if (!mConflictingQsExpansionGesture && !mShouldUseSplitNotificationShade) {
return true;
}
}
@@ -2121,7 +2049,7 @@ public class NotificationPanelViewController extends PanelViewController
< mStatusBarMinHeight) {
mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
mQsExpandImmediate = true;
- mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+ setShowShelfOnly(true);
requestPanelHeightUpdate();
// Normally, we start listening when the panel is expanded, but here we need to start
@@ -2192,6 +2120,9 @@ public class NotificationPanelViewController extends PanelViewController
if (!isFullyCollapsed()) {
return;
}
+ if (mShouldUseSplitNotificationShade) {
+ mQsExpandImmediate = true;
+ }
mExpectingSynthesizedDown = true;
onTrackingStarted();
updatePanelExpanded();
@@ -2398,12 +2329,10 @@ public class NotificationPanelViewController extends PanelViewController
}
private void updateQsState() {
- mNotificationStackScrollLayoutController.setQsExpanded(mQsExpanded);
+ boolean qsFullScreen = mQsExpanded && !mShouldUseSplitNotificationShade;
+ mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen);
mNotificationStackScrollLayoutController.setScrollingEnabled(
- mBarState != KEYGUARD
- && (!mQsExpanded
- || mQsExpansionFromOverscroll
- || mShouldUseSplitNotificationShade));
+ mBarState != KEYGUARD && (!qsFullScreen || mQsExpansionFromOverscroll));
if (mKeyguardUserSwitcherController != null && mQsExpanded
&& !mStackScrollerOverscrolling) {
@@ -2448,7 +2377,7 @@ public class NotificationPanelViewController extends PanelViewController
private void updateQsExpansion() {
if (mQs == null) return;
final float squishiness;
- if (mQsExpandImmediate || mQsExpanded) {
+ if ((mQsExpandImmediate || mQsExpanded) && !mShouldUseSplitNotificationShade) {
squishiness = 1;
} else if (mLockscreenShadeTransitionController.getQSDragProgress() > 0) {
squishiness = mLockscreenShadeTransitionController.getQSDragProgress();
@@ -2483,10 +2412,6 @@ public class NotificationPanelViewController extends PanelViewController
mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
mSplitShadeHeaderController.setShadeExpanded(mQsVisible);
-
- if (mCommunalViewController != null) {
- mCommunalViewController.updateQsExpansion(qsExpansionFraction);
- }
}
private void onStackYChanged(boolean shouldAnimate) {
@@ -2849,10 +2774,6 @@ public class NotificationPanelViewController extends PanelViewController
}
mTransitionToFullShadeQSPosition = position;
updateQsExpansion();
-
- if (mCommunalViewController != null) {
- mCommunalViewController.updateShadeExpansion(mTransitioningToFullShadeProgress);
- }
}
/**
@@ -2876,7 +2797,6 @@ public class NotificationPanelViewController extends PanelViewController
updateKeyguardBottomAreaAlpha();
}
updateClock();
- updateCommunal();
}
private void trackMovement(MotionEvent event) {
@@ -3305,7 +3225,7 @@ public class NotificationPanelViewController extends PanelViewController
setListening(true);
}
mQsExpandImmediate = false;
- mNotificationStackScrollLayoutController.setShouldShowShelfOnly(false);
+ setShowShelfOnly(false);
mTwoFingerQsExpandPossible = false;
updateTrackingHeadsUp(null);
mExpandingFromHeadsUp = false;
@@ -3361,9 +3281,7 @@ public class NotificationPanelViewController extends PanelViewController
mScrimController.onTrackingStarted();
if (mQsFullyExpanded) {
mQsExpandImmediate = true;
- if (!mShouldUseSplitNotificationShade) {
- mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
- }
+ setShowShelfOnly(true);
}
if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
mAffordanceHelper.animateHideLeftRightIcon();
@@ -3466,9 +3384,7 @@ public class NotificationPanelViewController extends PanelViewController
boolean wasRunning = isLaunchTransitionRunning();
super.setIsLaunchAnimationRunning(running);
if (wasRunning != isLaunchTransitionRunning()) {
- for (Callbacks cb : mNotifEventSourceCallbacks) {
- cb.onLaunchingActivityChanged(running);
- }
+ mPanelEventsEmitter.notifyLaunchingActivityChanged(running);
}
}
@@ -3477,9 +3393,7 @@ public class NotificationPanelViewController extends PanelViewController
boolean wasClosing = isClosing();
super.setIsClosing(isClosing);
if (wasClosing != isClosing) {
- for (Callbacks cb : mNotifEventSourceCallbacks) {
- cb.onPanelCollapsingChanged(isClosing);
- }
+ mPanelEventsEmitter.notifyPanelCollapsingChanged(isClosing);
}
}
@@ -4072,10 +3986,6 @@ public class NotificationPanelViewController extends PanelViewController
mNotificationStackScrollLayoutController.runAfterAnimationFinished(r);
}
- public void setScrollingEnabled(boolean b) {
- mNotificationStackScrollLayoutController.setScrollingEnabled(b);
- }
-
private Runnable mHideExpandedRunnable;
private final Runnable mMaybeHideExpandedRunnable = new Runnable() {
@Override
@@ -4381,16 +4291,6 @@ public class NotificationPanelViewController extends PanelViewController
.commitUpdate(mDisplayId);
}
- @Override
- public void registerCallbacks(Callbacks callbacks) {
- mNotifEventSourceCallbacks.addIfAbsent(callbacks);
- }
-
- @Override
- public void unregisterCallbacks(Callbacks callbacks) {
- mNotifEventSourceCallbacks.remove(callbacks);
- }
-
private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener {
@Override
public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
@@ -4770,14 +4670,6 @@ public class NotificationPanelViewController extends PanelViewController
goingToFullShade,
mBarState);
- if (mCommunalViewController != null) {
- mCommunalViewController.setKeyguardStatusViewVisibility(
- statusBarState,
- keyguardFadingAway,
- goingToFullShade,
- mBarState);
- }
-
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
mBarState = statusBarState;
@@ -4905,25 +4797,6 @@ public class NotificationPanelViewController extends PanelViewController
setExpandedFraction(1f);
}
- private void setCommunalSource(WeakReference<CommunalSource> source) {
- CommunalSource existingSource = mCommunalSource != null ? mCommunalSource.get() : null;
-
- if (existingSource != null) {
- mCommunalViewController.show(null /*source*/);
- }
-
- mCommunalSource = source;
-
- CommunalSource currentSource = mCommunalSource != null ? mCommunalSource.get() : null;
- // Set source and register callback
- if (currentSource != null && mCommunalViewController != null) {
- mCommunalViewController.show(source);
- }
-
- updateKeyguardStatusViewAlignment(true /*animate*/);
- updateMaxDisplayedNotifications(true /*recompute*/);
- }
-
/**
* Sets the overstretch amount in raw pixels when dragging down.
*/
@@ -4941,7 +4814,6 @@ public class NotificationPanelViewController extends PanelViewController
.addTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mConfigurationController.addCallback(mConfigurationListener);
- mCommunalSourceMonitor.addCallback(mCommunalSourceMonitorCallback);
// Theme might have changed between inflating this view and attaching it to the
// window, so
// force a call to onThemeChanged
@@ -4949,7 +4821,6 @@ public class NotificationPanelViewController extends PanelViewController
mFalsingManager.addTapListener(mFalsingTapListener);
mKeyguardIndicationController.init();
registerSettingsChangeListener();
- mCommunalStateController.addCallback(mCommunalStateCallback);
}
@Override
@@ -4959,9 +4830,7 @@ public class NotificationPanelViewController extends PanelViewController
.removeTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mConfigurationController.removeCallback(mConfigurationListener);
- mCommunalSourceMonitor.removeCallback(mCommunalSourceMonitorCallback);
mFalsingManager.removeTapListener(mFalsingTapListener);
- mCommunalStateController.removeCallback(mCommunalStateCallback);
}
}
@@ -5027,7 +4896,11 @@ public class NotificationPanelViewController extends PanelViewController
private void updateQSMinHeight() {
float previousMin = mQsMinExpansionHeight;
- mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight();
+ if (mKeyguardShowing || mShouldUseSplitNotificationShade) {
+ mQsMinExpansionHeight = 0;
+ } else {
+ mQsMinExpansionHeight = mQs.getQsMinExpansionHeight();
+ }
if (mQsExpansionHeight == previousMin) {
mQsExpansionHeight = mQsMinExpansionHeight;
}
@@ -5164,4 +5037,35 @@ public class NotificationPanelViewController extends PanelViewController
1.0f /* speedUpFactor */);
}
}
+
+ @SysUISingleton
+ static class PanelEventsEmitter implements NotifPanelEvents {
+
+ private final ListenerSet<Listener> mListeners = new ListenerSet<>();
+
+ @Inject
+ PanelEventsEmitter() {}
+
+ @Override
+ public void registerListener(@NonNull Listener listener) {
+ mListeners.addIfAbsent(listener);
+ }
+
+ @Override
+ public void unregisterListener(@NonNull Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void notifyLaunchingActivityChanged(boolean isLaunchingActivity) {
+ for (Listener cb : mListeners) {
+ cb.onLaunchingActivityChanged(isLaunchingActivity);
+ }
+ }
+
+ private void notifyPanelCollapsingChanged(boolean isCollapsing) {
+ for (NotifPanelEvents.Listener cb : mListeners) {
+ cb.onPanelCollapsingChanged(isCollapsing);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
index 7c9e597e74a1..ebb09b1af5e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
@@ -1,6 +1,7 @@
package com.android.systemui.statusbar.phone
import android.view.WindowInsets
+import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.navigationbar.NavigationModeController
@@ -41,6 +42,7 @@ class NotificationsQSContainerController @Inject constructor(
private var isQSCustomizerAnimating = false
private var notificationsBottomMargin = 0
+ private var scrimShadeBottomMargin = 0
private var bottomStableInsets = 0
private var bottomCutoutInsets = 0
@@ -67,17 +69,36 @@ class NotificationsQSContainerController @Inject constructor(
public override fun onViewAttached() {
updateMargins()
+ updateResources()
overviewProxyService.addCallback(taskbarVisibilityListener)
mView.setInsetsChangedListener(windowInsetsListener)
mView.setQSFragmentAttachedListener { qs: QS -> qs.setContainerController(this) }
+ mView.setConfigurationChangedListener { updateResources() }
}
override fun onViewDetached() {
overviewProxyService.removeCallback(taskbarVisibilityListener)
mView.removeOnInsetsChangedListener()
mView.removeQSFragmentAttachedListener()
+ mView.setConfigurationChangedListener(null)
}
+ private fun updateResources() {
+ val previousScrimShadeBottomMargin = scrimShadeBottomMargin
+ scrimShadeBottomMargin = resources.getDimensionPixelSize(
+ R.dimen.split_shade_notifications_scrim_margin_bottom
+ )
+
+ if (previousScrimShadeBottomMargin != scrimShadeBottomMargin) {
+ updateBottomSpacing()
+ }
+ }
+
+ /**
+ * Update the notification bottom margin.
+ *
+ * Will not call updateBottomSpacing
+ */
fun updateMargins() {
notificationsBottomMargin = mView.defaultNotificationsMarginBottom
}
@@ -111,7 +132,11 @@ class NotificationsQSContainerController @Inject constructor(
qsScrollPaddingBottom = bottomStableInsets
} else if (newFooter && !(isQSCustomizing || isQSDetailShowing)) {
// With the new footer, we also want this padding in the bottom in these cases
- qsScrollPaddingBottom = bottomStableInsets
+ qsScrollPaddingBottom = if (splitShadeEnabled) {
+ notificationsMargin - scrimShadeBottomMargin
+ } else {
+ bottomStableInsets
+ }
}
mView.setPadding(0, 0, 0, containerPadding)
mView.setNotificationsMarginBottom(notificationsMargin)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 95e3b70b4c5e..c2b5f5657fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -18,11 +18,13 @@ package com.android.systemui.statusbar.phone;
import android.app.Fragment;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowInsets;
+import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.systemui.R;
@@ -54,6 +56,9 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
private View mQSScrollView;
private View mQSContainer;
+ @Nullable
+ private Consumer<Configuration> mConfigurationChangedListener;
+
public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -79,6 +84,18 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
invalidate();
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (mConfigurationChangedListener != null) {
+ mConfigurationChangedListener.accept(newConfig);
+ }
+ }
+
+ public void setConfigurationChangedListener(Consumer<Configuration> listener) {
+ mConfigurationChangedListener = listener;
+ }
+
public void setNotificationsMarginBottom(int margin) {
LayoutParams params = (LayoutParams) mStackScroller.getLayoutParams();
params.bottomMargin = margin;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 7c1775ed2a5e..1d560c4592a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -397,6 +397,7 @@ public abstract class PanelViewController {
private void endMotionEvent(MotionEvent event, float x, float y, boolean forceCancel) {
mTrackingPointer = -1;
+ mAmbientState.setSwipingUp(false);
if ((mTracking && mTouchSlopExceeded) || Math.abs(x - mInitialTouchX) > mTouchSlop
|| Math.abs(y - mInitialTouchY) > mTouchSlop
|| event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
@@ -460,7 +461,6 @@ public abstract class PanelViewController {
boolean expands = onEmptySpaceClick(mInitialTouchX);
onTrackingStopped(expands);
}
- mAmbientState.setSwipingUp(false);
mVelocityTracker.clear();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index edbddbb3c3e7..108d98a129b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -41,6 +41,7 @@ import android.text.TextUtils;
import android.util.EventLog;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
@@ -51,6 +52,7 @@ import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.EventLogTags;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
@@ -75,6 +77,7 @@ import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ListenerSet;
import com.android.systemui.wmshell.BubblesManager;
import java.util.Optional;
@@ -128,6 +131,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
private final ActivityLaunchAnimator mActivityLaunchAnimator;
private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
private final OnUserInteractionCallback mOnUserInteractionCallback;
+ private final LaunchEventsEmitter mLaunchEventsEmitter;
private boolean mIsCollapsingToShowActivityOverLockscreen;
@@ -166,7 +170,8 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
NotificationPresenter presenter,
NotificationPanelViewController panel,
ActivityLaunchAnimator activityLaunchAnimator,
- NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
+ NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
+ LaunchEventsEmitter launchEventsEmitter) {
mContext = context;
mCommandQueue = commandQueue;
mMainThreadHandler = mainThreadHandler;
@@ -192,18 +197,17 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mLockPatternUtils = lockPatternUtils;
mStatusBarRemoteInputCallback = remoteInputCallback;
mActivityIntentHelper = activityIntentHelper;
-
mNotifPipelineFlags = notifPipelineFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
mOnUserInteractionCallback = onUserInteractionCallback;
-
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mCentralSurfaces = centralSurfaces;
mPresenter = presenter;
mNotificationPanel = panel;
mActivityLaunchAnimator = activityLaunchAnimator;
mNotificationAnimationProvider = notificationAnimationProvider;
+ mLaunchEventsEmitter = launchEventsEmitter;
if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@@ -254,6 +258,8 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
return;
}
+ mLaunchEventsEmitter.notifyStartLaunchNotifActivity(entry);
+
boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
final boolean willLaunchResolverActivity = isActivityIntent
&& mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
@@ -280,7 +286,9 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
postKeyguardAction.onDismiss();
} else {
mActivityStarter.dismissKeyguardThenExecute(
- postKeyguardAction, null /* cancel */, willLaunchResolverActivity);
+ postKeyguardAction,
+ () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry),
+ willLaunchResolverActivity);
}
}
@@ -380,24 +388,26 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
// inform NMS that the notification was clicked
mClickNotifier.onNotificationClick(notificationKey, nv);
- if (!canBubble) {
- if (shouldAutoCancel || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
- notificationKey)) {
- // Immediately remove notification from visually showing.
- // We have to post the removal to the UI thread for synchronization.
- mMainThreadHandler.post(() -> {
- final Runnable removeNotification = () ->
- mOnUserInteractionCallback.onDismiss(
- entry, REASON_CLICK, summaryToRemove);
- if (mPresenter.isCollapsing()) {
- // To avoid lags we're only performing the remove
- // after the shade is collapsed
- mShadeController.addPostCollapseAction(removeNotification);
- } else {
- removeNotification.run();
- }
- });
- }
+ if (!canBubble && (shouldAutoCancel
+ || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(notificationKey))) {
+ // Immediately remove notification from visually showing.
+ // We have to post the removal to the UI thread for synchronization.
+ mMainThreadHandler.post(() -> {
+ final Runnable removeNotification = () -> {
+ mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK, summaryToRemove);
+ mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry);
+ };
+ if (mPresenter.isCollapsing()) {
+ // To avoid lags we're only performing the remove
+ // after the shade is collapsed
+ mShadeController.addPostCollapseAction(removeNotification);
+ } else {
+ removeNotification.run();
+ }
+ });
+ } else {
+ mMainThreadHandler.post(
+ () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry));
}
mIsCollapsingToShowActivityOverLockscreen = false;
@@ -659,4 +669,35 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
return entry.shouldSuppressFullScreenIntent();
}
+
+ @SysUISingleton
+ static class LaunchEventsEmitter implements NotifActivityLaunchEvents {
+
+ private final ListenerSet<Listener> mListeners = new ListenerSet<>();
+
+ @Inject
+ LaunchEventsEmitter() {}
+
+ @Override
+ public void registerListener(@NonNull Listener listener) {
+ mListeners.addIfAbsent(listener);
+ }
+
+ @Override
+ public void unregisterListener(@NonNull Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void notifyStartLaunchNotifActivity(NotificationEntry entry) {
+ for (Listener listener : mListeners) {
+ listener.onStartLaunchNotifActivity(entry);
+ }
+ }
+
+ private void notifyFinishLaunchNotifActivity(NotificationEntry entry) {
+ for (Listener listener : mListeners) {
+ listener.onFinishLaunchNotifActivity(entry);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 59c9d0baea3f..a86ad6bc7012 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -27,7 +27,6 @@ import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.core.StatusBarInitializer;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.collection.render.StatusBarNotifPanelEventSourceModule;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
@@ -60,8 +59,8 @@ import dagger.Subcomponent;
* outside the component. Should more items be moved *into* this component to avoid so many getters?
*/
@Subcomponent(modules = {
+ CentralSurfacesStartableModule.class,
NotificationStackScrollLayoutListContainerModule.class,
- StatusBarNotifPanelEventSourceModule.class,
StatusBarViewModule.class,
StatusBarNotificationActivityStarterModule.class,
StatusBarNotificationPresenterModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
index 2894780e04b8..21e5ad5778b1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 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,13 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.dagger;
+package com.android.systemui.statusbar.phone.dagger;
+
+import java.util.Set;
import dagger.Module;
+import dagger.multibindings.Multibinds;
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
+@Module
+interface CentralSurfacesStartableModule {
+ @Multibinds
+ Set<CentralSurfacesComponent.Startable> multibindStartables();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 982ccfd4dffa..6ee65ae7e2ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -21,8 +21,8 @@ import android.app.IActivityManager
import android.app.IUidObserver
import android.app.Notification
import android.app.Notification.CallStyle.CALL_TYPE_ONGOING
+import android.app.PendingIntent
import android.content.Context
-import android.content.Intent
import android.util.Log
import android.view.View
import androidx.annotation.VisibleForTesting
@@ -95,7 +95,7 @@ class OngoingCallController @Inject constructor(
val newOngoingCallInfo = CallNotificationInfo(
entry.sbn.key,
entry.sbn.notification.`when`,
- entry.sbn.notification.contentIntent?.intent,
+ entry.sbn.notification.contentIntent,
entry.sbn.uid,
entry.sbn.notification.extras.getInt(
Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING,
@@ -227,7 +227,6 @@ class OngoingCallController @Inject constructor(
logger.logChipClicked()
activityStarter.postStartActivityDismissingKeyguard(
intent,
- 0,
ActivityLaunchAnimator.Controller.fromView(
backgroundView,
InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
@@ -301,7 +300,7 @@ class OngoingCallController @Inject constructor(
private data class CallNotificationInfo(
val key: String,
val callStartTime: Long,
- val intent: Intent?,
+ val intent: PendingIntent?,
val uid: Int,
/** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
val isOngoing: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index 7e2488f1dfab..e8bf89a6a90a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -35,7 +35,6 @@ import com.android.keyguard.KeyguardVisibilityHelper;
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
-import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
@@ -119,7 +118,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
@Main Resources resources,
ScreenLifecycle screenLifecycle,
UserSwitcherController userSwitcherController,
- CommunalStateController communalStateController,
KeyguardStateController keyguardStateController,
FalsingManager falsingManager,
ConfigurationController configurationController,
@@ -138,10 +136,9 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
mFalsingManager = falsingManager;
mConfigurationController = configurationController;
mStatusBarStateController = statusBarStateController;
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
+ mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
keyguardStateController, dozeParameters,
- screenOffAnimationController, /* animateYPos= */ false,
- /* visibleOnCommunal= */ false);
+ screenOffAnimationController, /* animateYPos= */ false);
mUserSwitchDialogController = userSwitchDialogController;
mUiEventLogger = uiEventLogger;
}
@@ -270,7 +267,7 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
}
- Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
+ Drawable bg = mContext.getDrawable(R.drawable.user_avatar_bg);
drawable = new LayerDrawable(new Drawable[]{bg, drawable});
return drawable;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index 04a6a114a07d..03ab888d1253 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -42,7 +42,6 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
-import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -158,7 +157,6 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
LayoutInflater layoutInflater,
ScreenLifecycle screenLifecycle,
UserSwitcherController userSwitcherController,
- CommunalStateController communalStateController,
KeyguardStateController keyguardStateController,
SysuiStatusBarStateController statusBarStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -174,10 +172,9 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater,
mUserSwitcherController, this);
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
+ mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
keyguardStateController, dozeParameters,
- screenOffAnimationController, /* animateYPos= */ false,
- /* visibleOnCommunal= */ false);
+ screenOffAnimationController, /* animateYPos= */ false);
mBackground = new KeyguardUserSwitcherScrim(context);
}
@@ -543,7 +540,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
}
drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
- Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
+ Drawable bg = mContext.getDrawable(R.drawable.user_avatar_bg);
drawable = new LayerDrawable(new Drawable[]{bg, drawable});
return drawable;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index d1c9b3f1c2c5..fa26a356f191 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -584,13 +584,6 @@ public class UserSwitcherController implements Dumpable {
.setPackage(mCreateSupervisedUserPackage)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- // TODO(b/209659998): [to-be-removed] fallback activity for supervised user creation.
- if (mContext.getPackageManager().resolveActivity(intent, 0) == null) {
- intent.setPackage(null)
- .setClassName("com.android.settings",
- "com.android.settings.users.AddSupervisedUserActivity");
- }
-
mContext.startActivity(intent);
}
@@ -855,8 +848,7 @@ public class UserSwitcherController implements Dumpable {
public @UserIdInt int createGuest() {
UserInfo guest;
try {
- guest = mUserManager.createGuest(mContext,
- mContext.getString(com.android.settingslib.R.string.guest_nickname));
+ guest = mUserManager.createGuest(mContext);
} catch (UserManager.UserOperationException e) {
Log.e(TAG, "Couldn't create guest user", e);
return UserHandle.USER_NULL;
@@ -990,9 +982,9 @@ public class UserSwitcherController implements Dumpable {
protected static Drawable getIconDrawable(Context context, UserRecord item) {
int iconRes;
if (item.isAddUser) {
- iconRes = R.drawable.ic_account_circle;
- } else if (item.isGuest) {
iconRes = R.drawable.ic_account_circle_filled;
+ } else if (item.isGuest) {
+ iconRes = R.drawable.ic_account_circle;
} else if (item.isAddSupervisedUser) {
iconRes = R.drawable.ic_add_supervised_user;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
index 89ab23b50cd8..117cba7401e9 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
@@ -18,7 +18,6 @@ package com.android.systemui.tv;
import com.android.systemui.dagger.GlobalModule;
import com.android.systemui.dagger.GlobalRootComponent;
-import com.android.systemui.dagger.WMModule;
import javax.inject.Singleton;
@@ -28,11 +27,7 @@ import dagger.Component;
* Root component for Dagger injection.
*/
@Singleton
-@Component(modules = {
- GlobalModule.class,
- TvSysUIComponentModule.class,
- WMModule.class
-})
+@Component(modules = {GlobalModule.class})
public interface TvGlobalRootComponent extends GlobalRootComponent {
/**
* Component Builder interface. This allows to bind Context instance in the component
@@ -42,9 +37,6 @@ public interface TvGlobalRootComponent extends GlobalRootComponent {
TvGlobalRootComponent build();
}
- /**
- * Builder for a WMComponent.
- */
@Override
TvWMComponent.Builder getWMComponentBuilder();
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 71d8e3344937..7e3bce589f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -199,10 +199,13 @@ public class Utils {
/**
* Gets the {@link R.dimen#split_shade_header_height}.
*
- * Currently, it's the same as {@link com.android.internal.R.dimen#quick_qs_offset_height}.
+ * It should be fine to not ignore cutouts as split shade might not want to react to them:
+ * for split shade header, which is only on bigger screens, either cutout won't be a problem
+ * (it's usually centered and in split shade that's likely empty area) or we probably want to
+ * handle it differently.
*/
public static int getSplitShadeStatusBarHeight(Context context) {
- return SystemBarUtils.getQuickQsOffsetHeight(context);
+ return context.getResources().getDimensionPixelSize(R.dimen.split_shade_header_height);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
index e8a9bc702352..8f61abcca4dc 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
@@ -25,10 +25,8 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.LongRunning;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
import dagger.Module;
import dagger.Provides;
@@ -149,18 +147,6 @@ public abstract class SysUIConcurrencyModule {
return new RepeatableExecutorImpl(exec);
}
- /**
- * Provide an Executor specifically for running UI operations on a separate thread.
- *
- * Keep submitted runnables short and to the point, just as with any other UI code.
- */
- @Provides
- @SysUISingleton
- @UiBackground
- public static Executor provideUiBackgroundExecutor() {
- return Executors.newSingleThreadExecutor();
- }
-
/** */
@Provides
@Main
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java b/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
index 2ee7b20c1f93..0d47d73153c1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
@@ -24,8 +24,6 @@ import android.content.IntentFilter;
import android.os.PatternMatcher;
import android.util.Log;
-import com.android.systemui.communal.CommunalSource;
-
import com.google.android.collect.Lists;
import java.lang.ref.WeakReference;
@@ -36,8 +34,8 @@ import javax.inject.Inject;
/**
* {@link PackageObserver} allows for monitoring the system for changes relating to a particular
- * package. This can be used by {@link CommunalSource} clients to detect when a related package
- * has changed and reloading is necessary.
+ * package. This can be used by clients to detect when a related package has changed and reloading
+ * is necessary.
*/
public class PackageObserver implements Observer {
private static final String TAG = "PackageObserver";
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 69ebfe8012d1..8a961942123b 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -749,6 +749,8 @@ public class BubblesManager implements Dumpable {
return;
}
+ entry.setFlagBubble(shouldBubble);
+
// Update the state in NotificationManagerService
try {
int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index c3c3f90539fd..60567c49bfdf 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -51,6 +51,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
@@ -116,6 +117,7 @@ public final class WMShell extends CoreStartable
private final CommandQueue mCommandQueue;
private final ConfigurationController mConfigurationController;
+ private final KeyguardStateController mKeyguardStateController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final NavigationModeController mNavigationModeController;
private final ScreenLifecycle mScreenLifecycle;
@@ -129,7 +131,7 @@ public final class WMShell extends CoreStartable
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
- private KeyguardUpdateMonitorCallback mCompatUIKeyguardCallback;
+ private KeyguardStateController.Callback mCompatUIKeyguardCallback;
private WakefulnessLifecycle.Observer mWakefulnessObserver;
@Inject
@@ -143,6 +145,7 @@ public final class WMShell extends CoreStartable
Optional<DragAndDrop> dragAndDropOptional,
CommandQueue commandQueue,
ConfigurationController configurationController,
+ KeyguardStateController keyguardStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
NavigationModeController navigationModeController,
ScreenLifecycle screenLifecycle,
@@ -154,6 +157,7 @@ public final class WMShell extends CoreStartable
super(context);
mCommandQueue = commandQueue;
mConfigurationController = configurationController;
+ mKeyguardStateController = keyguardStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mNavigationModeController = navigationModeController;
mScreenLifecycle = screenLifecycle;
@@ -362,13 +366,13 @@ public final class WMShell extends CoreStartable
@VisibleForTesting
void initCompatUi(CompatUI sizeCompatUI) {
- mCompatUIKeyguardCallback = new KeyguardUpdateMonitorCallback() {
+ mCompatUIKeyguardCallback = new KeyguardStateController.Callback() {
@Override
- public void onKeyguardOccludedChanged(boolean occluded) {
- sizeCompatUI.onKeyguardOccludedChanged(occluded);
+ public void onKeyguardShowingChanged() {
+ sizeCompatUI.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
}
};
- mKeyguardUpdateMonitor.registerCallback(mCompatUIKeyguardCallback);
+ mKeyguardStateController.addCallback(mCompatUIKeyguardCallback);
}
void initDragAndDrop(DragAndDrop dragAndDrop) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 8e1e42a9c9a2..e980eb783d79 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -88,6 +88,6 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
fun onPause_clearsTextField() {
mKeyguardPatternViewController.init()
mKeyguardPatternViewController.onPause()
- verify(mKeyguardMessageAreaController).setMessage("")
+ verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 217092e6e4e5..2fc912288623 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -22,7 +22,6 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -50,8 +49,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
- private CommunalStateController mCommunalStateController;
- @Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
ConfigurationController mConfigurationController;
@@ -76,7 +73,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mKeyguardClockSwitchController,
mKeyguardStateController,
mKeyguardUpdateMonitor,
- mCommunalStateController,
mConfigurationController,
mDozeParameters,
mKeyguardUnlockAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java
deleted file mode 100644
index a93a15df5986..000000000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java
+++ /dev/null
@@ -1,92 +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.keyguard;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-public class KeyguardVisibilityHelperTest extends SysuiTestCase {
- @Mock
- private CommunalStateController mCommunalStateController;
- @Mock
- private KeyguardStateController mKeyguardStateController;
- @Mock
- com.android.systemui.statusbar.phone.DozeParameters mDozeParameters;
- @Mock
- ScreenOffAnimationController mScreenOffAnimationController;
- @Mock
- ViewPropertyAnimator mViewPropertyAnimator;
- @Mock
- View mTargetView;
-
- private KeyguardVisibilityHelper mKeyguardVisibilityHelper;
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- when(mTargetView.animate()).thenReturn(mViewPropertyAnimator);
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
- mCommunalStateController, mKeyguardStateController, mDozeParameters,
- mScreenOffAnimationController, false, false);
- }
-
- @Test
- public void testHideOnCommunal() {
- // Verify view is hidden when communal is visible.
- when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
- mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
- false, StatusBarState.KEYGUARD);
- verify(mTargetView).setVisibility(View.GONE);
- verify(mTargetView).setAlpha(1.0f);
-
- // Verify view is shown when communal is not visible.
- when(mCommunalStateController.getCommunalViewShowing()).thenReturn(false);
- mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
- false, StatusBarState.KEYGUARD);
- verify(mTargetView).setVisibility(View.VISIBLE);
- }
-
- @Test
- public void testVisibleOnCommunal() {
- when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
- when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
- // Verify that helpers constructed with visibility on communal are not hidden when communal
- // is present.
- mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
- mCommunalStateController, mKeyguardStateController, mDozeParameters,
- mScreenOffAnimationController, false, true);
- mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
- false, StatusBarState.KEYGUARD);
- verify(mTargetView).setVisibility(View.VISIBLE);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java
deleted file mode 100644
index 8bd5e793dcdd..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.testing.AndroidTestingRunner;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.lang.ref.WeakReference;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalHostViewControllerTest extends SysuiTestCase {
- @Mock
- private CommunalStateController mCommunalStateController;
-
- @Mock
- private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-
- @Mock
- private KeyguardStateController mKeyguardStateController;
-
- @Mock
- private StatusBarStateController mStatusBarStateController;
-
- @Mock
- private CommunalHostView mCommunalView;
-
- @Mock
- private DozeParameters mDozeParameters;
-
- @Mock
- private ScreenOffAnimationController mScreenOffAnimationController;
-
- private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
-
- private CommunalHostViewController mController;
-
- @Mock
- private CommunalSource mCommunalSource;
-
- @Mock
- private View mChildView;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
-
- when(mKeyguardStateController.isShowing()).thenReturn(true);
- when(mCommunalView.isAttachedToWindow()).thenReturn(true);
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
-
- mController = new CommunalHostViewController(mFakeExecutor, mCommunalStateController,
- mKeyguardUpdateMonitor, mKeyguardStateController, mDozeParameters,
- mScreenOffAnimationController, mStatusBarStateController, mCommunalView);
- mController.init();
- mFakeExecutor.runAllReady();
-
- Mockito.clearInvocations(mCommunalView);
- }
-
- @Test
- public void testShow() {
- ArgumentCaptor<KeyguardStateController.Callback> callbackCapture =
- ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
-
- // Capture callback value for later use.
- verify(mKeyguardStateController).addCallback(callbackCapture.capture());
-
- // Verify the communal view is shown when the controller is initialized with keyguard
- // showing (see setup).
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
- verify(mCommunalView).setVisibility(View.VISIBLE);
-
- // Trigger keyguard off to ensure visibility of communal view is changed accordingly.
- when(mKeyguardStateController.isShowing()).thenReturn(false);
- callbackCapture.getValue().onKeyguardShowingChanged();
- mFakeExecutor.runAllReady();
- verify(mCommunalView).setVisibility(View.INVISIBLE);
- }
-
- @Test
- public void testHideOnOcclude() {
- ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
- ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
- // Capture callback value for later use.
- verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
- // Establish a visible communal view.
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
- verify(mCommunalView).setVisibility(View.VISIBLE);
- Mockito.clearInvocations(mCommunalView);
-
- // Occlude.
- Mockito.clearInvocations(mCommunalView);
- callbackCapture.getValue().onKeyguardOccludedChanged(true);
- mFakeExecutor.runAllReady();
- verify(mCommunalView).setVisibility(View.INVISIBLE);
-
- // Unocclude.
- Mockito.clearInvocations(mCommunalView);
- callbackCapture.getValue().onKeyguardOccludedChanged(false);
- mFakeExecutor.runAllReady();
- verify(mCommunalView).setVisibility(View.VISIBLE);
- }
-
- @Test
- public void testReportOcclusion() {
- // Ensure CommunalHostViewController reports view occluded when either the QS or Shade is
- // expanded.
- clearInvocations(mCommunalStateController);
- mController.updateShadeExpansion(0);
- verify(mCommunalStateController).setCommunalViewOccluded(false);
- clearInvocations(mCommunalStateController);
- mController.updateQsExpansion(.5f);
- verify(mCommunalStateController).setCommunalViewOccluded(true);
- clearInvocations(mCommunalStateController);
- mController.updateShadeExpansion(.7f);
- verify(mCommunalStateController).setCommunalViewOccluded(true);
- clearInvocations(mCommunalStateController);
- mController.updateShadeExpansion(0);
- verify(mCommunalStateController).setCommunalViewOccluded(true);
- clearInvocations(mCommunalStateController);
- mController.updateQsExpansion(0f);
- verify(mCommunalStateController).setCommunalViewOccluded(false);
- clearInvocations(mCommunalStateController);
- }
-
- @Test
- public void testCommunalStateControllerHideNotified() {
- ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
- ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
- // Capture callback value for later use.
- verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
- // Establish a visible communal view.
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
-
- // Occlude
- clearInvocations(mCommunalStateController);
- callbackCapture.getValue().onKeyguardOccludedChanged(true);
- mFakeExecutor.runAllReady();
-
- // Verify state controller is notified communal view is hidden.
- verify(mCommunalStateController).setCommunalViewShowing(false);
- }
-
- @Test
- public void testAlphaPropagation() {
- final float alpha = 0.8f;
-
- // Ensure alpha setting is propagated to children.
- when(mCommunalView.getChildCount()).thenReturn(1);
- when(mCommunalView.getChildAt(0)).thenReturn(mChildView);
- mController.setAlpha(alpha);
- verify(mChildView).setAlpha(alpha);
- verify(mCommunalView).setAlpha(alpha);
- }
-
- @Test
- public void testMultipleShowRequestSuppression() {
- // Ensure first request invokes source.
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
- verify(mCommunalSource).requestCommunalView(any());
- clearInvocations(mCommunalSource);
-
- // Ensure subsequent identical request is suppressed
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
- verify(mCommunalSource, never()).requestCommunalView(any());
- }
-
- @Test
- public void testNoShowInvocationOnBouncer() {
- ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
- ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
- // Capture callback value for later use.
- verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
- // Set source so it will be cleared if in invalid state.
- mController.show(new WeakReference<>(mCommunalSource));
- mFakeExecutor.runAllReady();
- clearInvocations(mCommunalStateController, mCommunalView);
-
- // Change bouncer to showing.
- callbackCapture.getValue().onKeyguardBouncerChanged(true);
- mFakeExecutor.runAllReady();
-
- // Verify that there were no requests to remove all child views or set the communal
- // state to not showing.
- verify(mCommunalStateController, never()).setCommunalViewShowing(eq(false));
- verify(mCommunalView, never()).removeAllViews();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java
deleted file mode 100644
index 0a0266bc1955..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalHostViewPositionAlgorithm.Result;
-
-import org.junit.Test;
-
-
-@SmallTest
-public class CommunalHostViewPositionAlgorithmTest extends SysuiTestCase {
- @Test
- public void testOutput() {
- final float expansion = 0.25f;
- final int height = 120;
-
- final CommunalHostViewPositionAlgorithm algorithm = new CommunalHostViewPositionAlgorithm();
- algorithm.setup(expansion, height);
- final Result result = new Result();
- algorithm.run(result);
-
- // Verify the communal view is shifted offscreen vertically by the correct amount.
- assertThat((1 - expansion) * -height).isEqualTo(result.communalY);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java
deleted file mode 100644
index c5b1a1d8bac5..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.conditions.CommunalSettingCondition;
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.settings.FakeSettings;
-import com.android.systemui.utils.os.FakeHandler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalSettingConditionTest extends SysuiTestCase {
- private FakeSettings mSecureSettings;
- private CommunalSettingCondition mCondition;
-
- @Before
- public void setup() {
- final FakeHandler handler = new FakeHandler(Looper.getMainLooper());
- mSecureSettings = new FakeSettings();
- mCondition = new CommunalSettingCondition(handler, mSecureSettings);
- }
-
- @Test
- public void addCallback_communalSettingEnabled_immediatelyReportsTrue() {
- updateCommunalSetting(true);
-
- final Condition.Callback callback = mock(Condition.Callback.class);
- mCondition.addCallback(callback);
- verify(callback).onConditionChanged(mCondition);
- assertThat(mCondition.isConditionMet()).isTrue();
- }
-
- @Test
- public void addCallback_communalSettingDisabled_noReport() {
- updateCommunalSetting(false);
-
- final Condition.Callback callback = mock(Condition.Callback.class);
- mCondition.addCallback(callback);
- verify(callback, never()).onConditionChanged(eq(mCondition));
- }
-
- @Test
- public void updateCallback_communalSettingEnabled_reportsTrue() {
- updateCommunalSetting(false);
-
- final Condition.Callback callback = mock(Condition.Callback.class);
- mCondition.addCallback(callback);
- clearInvocations(callback);
-
- updateCommunalSetting(true);
- verify(callback).onConditionChanged(mCondition);
- assertThat(mCondition.isConditionMet()).isTrue();
- }
-
- @Test
- public void updateCallback_communalSettingDisabled_reportsFalse() {
- updateCommunalSetting(true);
-
- final Condition.Callback callback = mock(Condition.Callback.class);
- mCondition.addCallback(callback);
- clearInvocations(callback);
-
- updateCommunalSetting(false);
- verify(callback).onConditionChanged(mCondition);
- assertThat(mCondition.isConditionMet()).isFalse();
- }
-
- @Test
- public void updateCallback_communalSettingDidNotChange_neverReportDup() {
- updateCommunalSetting(true);
-
- final Condition.Callback callback = mock(Condition.Callback.class);
- mCondition.addCallback(callback);
- clearInvocations(callback);
-
- updateCommunalSetting(true);
- verify(callback, never()).onConditionChanged(mCondition);
- assertThat(mCondition.isConditionMet()).isTrue();
- }
-
- private void updateCommunalSetting(boolean value) {
- mSecureSettings.putIntForUser(Settings.Secure.COMMUNAL_MODE_ENABLED, value ? 1 : 0,
- UserHandle.USER_SYSTEM);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java
deleted file mode 100644
index df1cc766d162..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.condition.Monitor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.lang.ref.WeakReference;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class CommunalSourceMonitorTest extends SysuiTestCase {
- @Mock private Monitor mCommunalConditionsMonitor;
-
- @Captor private ArgumentCaptor<Monitor.Callback> mConditionsCallbackCaptor;
-
- private CommunalSourceMonitor mCommunalSourceMonitor;
- private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mCommunalSourceMonitor = new CommunalSourceMonitor(mExecutor, mCommunalConditionsMonitor);
- }
-
- @Test
- public void testSourceAddedBeforeCallbackAdded() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- setSource(source);
- mCommunalSourceMonitor.addCallback(callback);
- setConditionsMet(true);
-
- verifyOnSourceAvailableCalledWith(callback, source);
- }
-
- @Test
- public void testRemoveCallback() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- mCommunalSourceMonitor.addCallback(callback);
- mCommunalSourceMonitor.removeCallback(callback);
- setSource(source);
-
- verify(callback, never()).onSourceAvailable(any());
- }
-
- @Test
- public void testAddCallbackWithConditionsMet() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- mCommunalSourceMonitor.addCallback(callback);
- setConditionsMet(true);
- clearInvocations(callback);
- setSource(source);
-
- verifyOnSourceAvailableCalledWith(callback, source);
- }
-
- @Test
- public void testAddCallbackWithConditionsNotMet() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- mCommunalSourceMonitor.addCallback(callback);
- setConditionsMet(false);
- setSource(source);
-
- verify(callback, never()).onSourceAvailable(any());
- }
-
- @Test
- public void testConditionsAreMetAfterCallbackAdded() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- mCommunalSourceMonitor.addCallback(callback);
- setSource(source);
-
- // The callback should not have executed since communal is disabled.
- verify(callback, never()).onSourceAvailable(any());
-
- // The callback should execute when all conditions are met.
- setConditionsMet(true);
- verifyOnSourceAvailableCalledWith(callback, source);
- }
-
- @Test
- public void testConditionsNoLongerMetAfterCallbackAdded() {
- final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
- final CommunalSource source = mock(CommunalSource.class);
-
- mCommunalSourceMonitor.addCallback(callback);
- setSource(source);
- setConditionsMet(true);
- verifyOnSourceAvailableCalledWith(callback, source);
-
- // The callback should execute again when conditions are no longer met, with a value of
- // null.
- setConditionsMet(false);
- verify(callback).onSourceAvailable(null);
- }
-
- private void verifyOnSourceAvailableCalledWith(CommunalSourceMonitor.Callback callback,
- CommunalSource source) {
- final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
- ArgumentCaptor.forClass(WeakReference.class);
- verify(callback).onSourceAvailable(sourceCapture.capture());
- assertThat(sourceCapture.getValue().get()).isEqualTo(source);
- }
-
- // Pushes an update on whether the communal conditions are met, assuming that a callback has
- // been registered with the communal conditions monitor.
- private void setConditionsMet(boolean value) {
- mExecutor.runAllReady();
- verify(mCommunalConditionsMonitor).addCallback(mConditionsCallbackCaptor.capture());
- final Monitor.Callback conditionsCallback =
- mConditionsCallbackCaptor.getValue();
- conditionsCallback.onConditionsChanged(value);
- mExecutor.runAllReady();
- }
-
- private void setSource(CommunalSource source) {
- mCommunalSourceMonitor.setSource(source);
- mExecutor.runAllReady();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java
deleted file mode 100644
index 1d9a0594d7e2..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.concurrency.FakeExecutor;;
-import com.android.systemui.util.ref.GcWeakReference;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalSourcePrimerTest extends SysuiTestCase {
- private static final String TEST_COMPONENT_NAME = "com.google.tests/.CommunalService";
- private static final int MAX_RETRIES = 5;
- private static final int RETRY_DELAY_MS = 1000;
- private static final int CONNECTION_MIN_DURATION_MS = 5000;
-
- // A simple implementation of {@link CommunalSource.Observer} to capture a callback value.
- // Used to ensure the references to a {@link CommunalSource.Observer.Callback} can be fully
- // removed.
- private static class FakeObserver implements CommunalSource.Observer {
- public GcWeakReference<Callback> mLastCallback;
-
- @Override
- public void addCallback(Callback callback) {
- mLastCallback = new GcWeakReference<>(callback);
- }
-
- @Override
- public void removeCallback(Callback callback) {
- if (mLastCallback.get() == callback) {
- mLastCallback = null;
- }
- }
- }
-
- // A simple implementation of {@link CommunalSource} to capture callback values. This
- // implementation better emulates the {@link WeakReference} wrapping behavior of
- // {@link CommunalSource} implementations than a mock.
- private static class FakeSource implements CommunalSource {
- @Override
- public ListenableFuture<CommunalViewResult> requestCommunalView(Context context) {
- return null;
- }
- }
-
- @Mock
- private Context mContext;
-
- @Mock
- private Resources mResources;
-
- private FakeSystemClock mFakeClock = new FakeSystemClock();
- private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
-
- private FakeSource mSource = new FakeSource();
-
- @Mock
- private CommunalSourceMonitor mCommunalSourceMonitor;
-
- @Mock
- private CommunalSource.Connector mConnector;
-
- @Mock
- private CommunalSource.Connection mConnection;
-
- private FakeObserver mObserver = new FakeObserver();
-
- private CommunalSourcePrimer mPrimer;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- when(mResources.getInteger(R.integer.config_communalSourceMaxReconnectAttempts))
- .thenReturn(MAX_RETRIES);
- when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
- .thenReturn(RETRY_DELAY_MS);
- when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
- .thenReturn(RETRY_DELAY_MS);
- when(mResources.getString(R.string.config_communalSourceComponent))
- .thenReturn(TEST_COMPONENT_NAME);
- when(mResources.getInteger(R.integer.config_connectionMinDuration))
- .thenReturn(CONNECTION_MIN_DURATION_MS);
-
- mPrimer = new CommunalSourcePrimer(mContext, mResources, mFakeClock, mFakeExecutor,
- mCommunalSourceMonitor, Optional.of(mConnector), Optional.of(mObserver));
- }
-
- private CommunalSource.Connection.Callback captureCallbackAndSend(
- CommunalSource.Connector connector, Optional<CommunalSource> source) {
- ArgumentCaptor<CommunalSource.Connection.Callback> connectionCallback =
- ArgumentCaptor.forClass(CommunalSource.Connection.Callback.class);
-
- verify(connector).connect(connectionCallback.capture());
- Mockito.clearInvocations(connector);
-
- final CommunalSource.Connection.Callback callback = connectionCallback.getValue();
- callback.onSourceEstablished(source);
-
- return callback;
- }
-
- @Test
- public void testConnect() {
- mPrimer.onBootCompleted();
- captureCallbackAndSend(mConnector, Optional.of(mSource));
- verify(mCommunalSourceMonitor).setSource(mSource);
- }
-
- @Test
- public void testRetryOnBindFailure() throws Exception {
- mPrimer.onBootCompleted();
-
- // Verify attempts happen. Note that we account for the retries plus initial attempt, which
- // is not scheduled.
- for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
- captureCallbackAndSend(mConnector, Optional.empty());
- mFakeExecutor.advanceClockToNext();
- mFakeExecutor.runAllReady();
- }
-
- verify(mCommunalSourceMonitor, never()).setSource(Mockito.notNull());
- }
-
- @Test
- public void testRetryOnDisconnectFailure() throws Exception {
- mPrimer.onBootCompleted();
- // Verify attempts happen. Note that we account for the retries plus initial attempt, which
- // is not scheduled.
- for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
- final CommunalSource.Connection.Callback callback =
- captureCallbackAndSend(mConnector, Optional.of(mSource));
- verify(mCommunalSourceMonitor).setSource(Mockito.notNull());
- clearInvocations(mCommunalSourceMonitor);
- callback.onDisconnected();
- mFakeExecutor.advanceClockToNext();
- mFakeExecutor.runAllReady();
- }
-
- verify(mConnector, never()).connect(any());
- }
-
- @Test
- public void testAttemptOnPackageChange() {
- mPrimer.onBootCompleted();
- captureCallbackAndSend(mConnector, Optional.empty());
-
- mObserver.mLastCallback.get().onSourceChanged();
-
- verify(mConnector, times(1)).connect(any());
- }
-
- @Test
- public void testDisconnect() {
- mPrimer.onBootCompleted();
- final CommunalSource.Connection.Callback callback =
- captureCallbackAndSend(mConnector, Optional.of(mSource));
- verify(mCommunalSourceMonitor).setSource(mSource);
-
- mFakeClock.advanceTime(CONNECTION_MIN_DURATION_MS + 1);
- callback.onDisconnected();
-
- verify(mConnector).connect(any());
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java
deleted file mode 100644
index 7f85c35af742..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalStateControllerTest extends SysuiTestCase {
- @Mock
- private CommunalStateController.Callback mCallback;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testDefaultCommunalViewShowingState() {
- // The state controller should report the communal view as not showing by default.
- final CommunalStateController stateController = new CommunalStateController();
- assertThat(stateController.getCommunalViewShowing()).isFalse();
- }
-
- @Test
- public void testNotifyCommunalSurfaceShow() {
- final CommunalStateController stateController = new CommunalStateController();
- stateController.addCallback(mCallback);
-
- // Verify setting communal view to showing propagates to callback.
- stateController.setCommunalViewShowing(true);
- verify(mCallback).onCommunalViewShowingChanged();
- assertThat(stateController.getCommunalViewShowing()).isTrue();
-
- clearInvocations(mCallback);
-
- // Verify setting communal view to not showing propagates to callback.
- stateController.setCommunalViewShowing(false);
- verify(mCallback).onCommunalViewShowingChanged();
- assertThat(stateController.getCommunalViewShowing()).isFalse();
- }
-
- @Test
- public void testCallbackRegistration() {
- final CommunalStateController stateController = new CommunalStateController();
- stateController.addCallback(mCallback);
-
- // Verify setting communal view to showing propagates to callback.
- stateController.setCommunalViewShowing(true);
- verify(mCallback).onCommunalViewShowingChanged();
-
- clearInvocations(mCallback);
-
- stateController.removeCallback(mCallback);
- clearInvocations(mCallback);
-
- // Verify callback not invoked after removing from state controller.
- stateController.setCommunalViewShowing(false);
- verify(mCallback, never()).onCommunalViewShowingChanged();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java
deleted file mode 100644
index 1cd60698353b..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.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.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.verify;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class PackageObserverTest extends SysuiTestCase {
- private static final String PACKAGE_NAME = "com.foo.bar";
-
- @Mock
- Context mContext;
-
- @Mock
- CommunalSource.Observer.Callback mCallback;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testChange() {
- final PackageObserver observer = new PackageObserver(mContext, PACKAGE_NAME);
- final ArgumentCaptor<BroadcastReceiver> receiverCapture =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
-
- observer.addCallback(mCallback);
-
- // Verify broadcast receiver registered.
- verify(mContext).registerReceiver(receiverCapture.capture(), any(), anyInt());
-
- // Simulate package change.
- receiverCapture.getValue().onReceive(mContext, new Intent());
-
- // Check that callback was informed.
- verify(mCallback).onSourceChanged();
-
- observer.removeCallback(mCallback);
-
- // Make sure receiver is unregistered on last callback removal
- verify(mContext).unregisterReceiver(receiverCapture.getValue());
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index b3d54590dc99..7d7ccb462b3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.dreams;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -173,19 +174,19 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
}
@Test
- public void testShouldShowComplicationsFalseByDefault() {
+ public void testShouldShowComplicationsTrueByDefault() {
mService.onBind(new Intent());
- assertThat(mService.shouldShowComplications()).isFalse();
+ assertThat(mService.shouldShowComplications()).isTrue();
}
@Test
public void testShouldShowComplicationsSetByIntentExtra() {
final Intent intent = new Intent();
- intent.putExtra(DreamService.EXTRA_SHOW_COMPLICATIONS, true);
+ intent.putExtra(DreamService.EXTRA_SHOW_COMPLICATIONS, false);
mService.onBind(intent);
- assertThat(mService.shouldShowComplications()).isTrue();
+ assertThat(mService.shouldShowComplications()).isFalse();
}
@Test
@@ -222,4 +223,25 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
verify(mLifecycleRegistry).setCurrentState(Lifecycle.State.DESTROYED);
verify(mStateController).setOverlayActive(false);
}
+
+ @Test
+ public void testDecorViewNotAddedToWindowAfterDestroy() throws Exception {
+ when(mDreamOverlayContainerView.getParent())
+ .thenReturn(mDreamOverlayContainerViewParent)
+ .thenReturn(null);
+
+ final IBinder proxy = mService.onBind(new Intent());
+ final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
+
+ // Inform the overlay service of dream starting.
+ overlay.startDream(mWindowParams, mDreamOverlayCallback);
+
+ // Destroy the service.
+ mService.onDestroy();
+
+ // Run executor tasks.
+ mMainExecutor.runAllReady();
+
+ verify(mWindowManager, never()).addView(any(), any());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 3ce9889571f1..49da4bd5a825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -158,7 +158,6 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
public void testComplicationFilteringWhenShouldShowComplications() {
final DreamOverlayStateController stateController =
new DreamOverlayStateController(mExecutor);
- stateController.setShouldShowComplications(true);
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
final Complication weatherComplication = Mockito.mock(Complication.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
index 3b17a8071cb2..ed1cf69ad8c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -15,26 +15,31 @@
*/
package com.android.systemui.dreams;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class SmartSpaceComplicationTest extends SysuiTestCase {
@@ -42,7 +47,7 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
private Context mContext;
@Mock
- private LockscreenSmartspaceController mSmartspaceController;
+ private DreamsSmartspaceController mSmartspaceController;
@Mock
private DreamOverlayStateController mDreamOverlayStateController;
@@ -60,7 +65,6 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
*/
@Test
public void testAvailability() {
- when(mSmartspaceController.isEnabled()).thenReturn(false);
final SmartSpaceComplication.Registrant registrant = new SmartSpaceComplication.Registrant(
mContext,
@@ -68,10 +72,22 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
mComplication,
mSmartspaceController);
registrant.start();
- verify(mDreamOverlayStateController, never()).addComplication(any());
+ verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
- when(mSmartspaceController.isEnabled()).thenReturn(true);
- registrant.start();
+
+ final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
+ ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+ verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
+
+ when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+ dreamCallbackCaptor.getValue().onStateChanged();
+
+ final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
+ ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
+ verify(mSmartspaceController).addListener(listenerCaptor.capture());
+
+ final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index 6fead9efa767..f00fbe6ac4d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -341,6 +341,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
public void testCreateActionItems_lockdownEnabled_doesShowLockdown() {
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
String[] actions = {
@@ -365,8 +366,10 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
public void testCreateActionItems_lockdownDisabled_doesNotShowLockdown() {
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
// make sure lockdown action will NOT be shown
doReturn(false).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
String[] actions = {
GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
// lockdown action not allowed
@@ -386,6 +389,32 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
}
@Test
+ public void testCreateActionItems_emergencyDisabled_doesNotShowEmergency() {
+ mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+ doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ // make sure emergency action will NOT be shown
+ doReturn(false).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+ String[] actions = {
+ // emergency action not allowed
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+ mGlobalActionsDialogLite.createActionItems();
+
+ assertItemsOfType(mGlobalActionsDialogLite.mItems,
+ GlobalActionsDialogLite.LockDownAction.class,
+ GlobalActionsDialogLite.ShutDownAction.class,
+ GlobalActionsDialogLite.RestartAction.class);
+ assertThat(mGlobalActionsDialogLite.mOverflowItems).isEmpty();
+ assertThat(mGlobalActionsDialogLite.mPowerItems).isEmpty();
+ }
+
+ @Test
public void testShouldLogLockdownPress() {
GlobalActionsDialogLite.LockDownAction lockDownAction =
mGlobalActionsDialogLite.new LockDownAction();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 2be30b39763e..13e582196ffb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -42,6 +42,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -50,6 +51,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Optional;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -66,6 +69,8 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
private NotificationEntryManager mNotificationEntryManager =
mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
+ private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+ NearbyMediaDevicesManager.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
@@ -80,7 +85,8 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+ mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext,
mMediaOutputController);
mMediaOutputBaseDialogImpl.onCreate(new Bundle());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 789822e262d5..6230700a6a2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -33,9 +33,11 @@ import android.content.Context;
import android.graphics.drawable.Icon;
import android.media.MediaDescription;
import android.media.MediaMetadata;
+import android.media.NearbyDevice;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
+import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.text.TextUtils;
@@ -51,17 +53,21 @@ import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -86,6 +92,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
+ private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
+ private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class);
private ShadeController mShadeController = mock(ShadeController.class);
@@ -93,12 +101,15 @@ public class MediaOutputControllerTest extends SysuiTestCase {
private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+ private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+ NearbyMediaDevicesManager.class);
private Context mSpyContext;
private MediaOutputController mMediaOutputController;
private LocalMediaManager mLocalMediaManager;
private List<MediaController> mMediaControllers = new ArrayList<>();
private List<MediaDevice> mMediaDevices = new ArrayList<>();
+ private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
private MediaDescription mMediaDescription;
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -115,7 +126,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+ mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
MediaDescription.Builder builder = new MediaDescription.Builder();
@@ -127,6 +139,13 @@ public class MediaOutputControllerTest extends SysuiTestCase {
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
mMediaDevices.add(mMediaDevice1);
mMediaDevices.add(mMediaDevice2);
+
+ when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
+ when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
+ when(mNearbyDevice2.getMediaRoute2Id()).thenReturn(TEST_DEVICE_2_ID);
+ when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
+ mNearbyDevices.add(mNearbyDevice1);
+ mNearbyDevices.add(mNearbyDevice2);
}
@Test
@@ -159,7 +178,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void start_withoutPackageName_verifyMediaControllerInit() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+ mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.start(mCb);
@@ -167,6 +187,13 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void start_nearbyMediaDevicesManagerNotNull_registersNearbyDevicesCallback() {
+ mMediaOutputController.start(mCb);
+
+ verify(mNearbyMediaDevicesManager).registerNearbyDevicesCallback(any());
+ }
+
+ @Test
public void stop_withPackageName_verifyMediaControllerDeinit() {
mMediaOutputController.start(mCb);
reset(mMediaController);
@@ -180,7 +207,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void stop_withoutPackageName_verifyMediaControllerDeinit() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+ mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.start(mCb);
@@ -189,6 +217,39 @@ public class MediaOutputControllerTest extends SysuiTestCase {
verify(mMediaController, never()).unregisterCallback(any());
}
+
+ @Test
+ public void stop_nearbyMediaDevicesManagerNotNull_unregistersNearbyDevicesCallback() {
+ mMediaOutputController.start(mCb);
+ reset(mMediaController);
+
+ mMediaOutputController.stop();
+
+ verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
+ }
+
+ @Test
+ public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
+ mMediaOutputController.start(mCb);
+
+ mMediaOutputController.onDevicesUpdated(ImmutableList.of());
+
+ verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
+ }
+
+ @Test
+ public void onDeviceListUpdate_withNearbyDevices_updatesRangeInformation()
+ throws RemoteException {
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+
+ mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+ verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_CLOSE);
+ verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_FAR);
+ }
+
@Test
public void onDeviceListUpdate_verifyDeviceListCallback() {
mMediaOutputController.start(mCb);
@@ -451,7 +512,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void getNotificationLargeIcon_withoutPackageName_returnsNull() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+ mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
assertThat(mMediaOutputController.getNotificationIcon()).isNull();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index 8a3ea562269d..cb52e7c20464 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -37,6 +37,7 @@ import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -48,6 +49,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -67,6 +69,8 @@ public class MediaOutputDialogTest extends SysuiTestCase {
mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+ private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+ NearbyMediaDevicesManager.class);
private MediaOutputDialog mMediaOutputDialog;
private MediaOutputController mMediaOutputController;
@@ -76,7 +80,8 @@ public class MediaOutputDialogTest extends SysuiTestCase {
public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+ mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
mMediaOutputDialog = new MediaOutputDialog(mContext, false,
mMediaOutputController, mUiEventLogger);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
index e8cd6c88956d..f186f57fd0e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
@@ -35,6 +35,7 @@ import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -46,6 +47,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -66,6 +68,8 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase {
mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+ private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+ NearbyMediaDevicesManager.class);
private MediaOutputGroupDialog mMediaOutputGroupDialog;
private MediaOutputController mMediaOutputController;
@@ -75,7 +79,8 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase {
public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
- mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+ mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false,
mMediaOutputController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
index 794bc09715af..2a130535c657 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
@@ -21,13 +21,8 @@ import android.content.Context
import android.media.MediaRoute2Info
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToEndCast
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToStartCast
-import com.android.systemui.media.taptotransfer.sender.TransferFailed
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceSucceeded
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverSucceeded
+import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.concurrency.FakeExecutor
@@ -88,7 +83,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_almostCloseToStartCast_serviceCallbackCalled() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(AlmostCloseToStartCast::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.ALMOST_CLOSE_TO_START_CAST.name)
)
val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -103,7 +98,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_almostCloseToEndCast_serviceCallbackCalled() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(AlmostCloseToEndCast::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.ALMOST_CLOSE_TO_END_CAST.name)
)
val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -118,7 +113,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_transferToReceiverTriggered_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(TransferToReceiverTriggered::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED.name)
)
val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -133,7 +128,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_transferToThisDeviceTriggered_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(TransferToThisDeviceTriggered::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED.name)
)
verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
@@ -146,7 +141,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_transferToReceiverSucceeded_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(TransferToReceiverSucceeded::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.name)
)
val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -161,7 +156,7 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun sender_transferToThisDeviceSucceeded_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(
- pw, getSenderCommand(TransferToThisDeviceSucceeded::class.simpleName!!)
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.name)
)
val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -174,8 +169,10 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
}
@Test
- fun sender_transferFailed_serviceCallbackCalled() {
- commandRegistry.onShellCommand(pw, getSenderCommand(TransferFailed::class.simpleName!!))
+ fun sender_transferToReceiverFailed_serviceCallbackCalled() {
+ commandRegistry.onShellCommand(
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED.name)
+ )
verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED),
@@ -185,8 +182,23 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
}
@Test
+ fun sender_transferToThisDeviceFailed_serviceCallbackCalled() {
+ commandRegistry.onShellCommand(
+ pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_FAILED.name)
+ )
+
+ verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
+ eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED),
+ any(),
+ nullable(),
+ nullable())
+ }
+
+ @Test
fun sender_farFromReceiver_serviceCallbackCalled() {
- commandRegistry.onShellCommand(pw, getSenderCommand(FAR_FROM_RECEIVER_STATE))
+ commandRegistry.onShellCommand(
+ pw, getSenderCommand(ChipStateSender.FAR_FROM_RECEIVER.name)
+ )
verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER),
@@ -197,7 +209,9 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun receiver_closeToSender_serviceCallbackCalled() {
- commandRegistry.onShellCommand(pw, getReceiverCommand(CLOSE_TO_SENDER_STATE))
+ commandRegistry.onShellCommand(
+ pw, getReceiverCommand(ChipStateReceiver.CLOSE_TO_SENDER.name)
+ )
verify(statusBarManager).updateMediaTapToTransferReceiverDisplay(
eq(StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER),
@@ -209,7 +223,9 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
@Test
fun receiver_farFromSender_serviceCallbackCalled() {
- commandRegistry.onShellCommand(pw, getReceiverCommand(FAR_FROM_SENDER_STATE))
+ commandRegistry.onShellCommand(
+ pw, getReceiverCommand(ChipStateReceiver.FAR_FROM_SENDER.name)
+ )
verify(statusBarManager).updateMediaTapToTransferReceiverDisplay(
eq(StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
index adb59eca1e08..ccce5778c150 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
@@ -17,7 +17,10 @@
package com.android.systemui.media.taptotransfer.common
import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
+import android.os.PowerManager
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
@@ -40,6 +43,7 @@ import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.Mock
+import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
@@ -48,12 +52,16 @@ import org.mockito.MockitoAnnotations
@SmallTest
class MediaTttChipControllerCommonTest : SysuiTestCase() {
- private lateinit var controllerCommon: MediaTttChipControllerCommon<MediaTttChipState>
+ private lateinit var controllerCommon: MediaTttChipControllerCommon<ChipInfo>
private lateinit var fakeClock: FakeSystemClock
private lateinit var fakeExecutor: FakeExecutor
- private lateinit var appIconDrawable: Drawable
+ private lateinit var appIconFromPackageName: Drawable
+ @Mock
+ private lateinit var packageManager: PackageManager
+ @Mock
+ private lateinit var applicationInfo: ApplicationInfo
@Mock
private lateinit var logger: MediaTttLogger
@Mock
@@ -62,25 +70,36 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
private lateinit var viewUtil: ViewUtil
@Mock
private lateinit var tapGestureDetector: TapGestureDetector
+ @Mock
+ private lateinit var powerManager: PowerManager
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- appIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
+
+ appIconFromPackageName = context.getDrawable(R.drawable.ic_cake)!!
+ whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(appIconFromPackageName)
+ whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
+ whenever(packageManager.getApplicationInfo(
+ eq(PACKAGE_NAME), any<PackageManager.ApplicationInfoFlags>()
+ )).thenReturn(applicationInfo)
+ context.setMockPackageManager(packageManager)
+
fakeClock = FakeSystemClock()
fakeExecutor = FakeExecutor(fakeClock)
controllerCommon = TestControllerCommon(
- context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector
+ context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector, powerManager
)
}
@Test
- fun displayChip_chipAddedAndGestureDetectionStarted() {
+ fun displayChip_chipAddedAndGestureDetectionStartedAndScreenOn() {
controllerCommon.displayChip(getState())
verify(windowManager).addView(any(), any())
verify(tapGestureDetector).addOnGestureDetectedCallback(any(), any())
+ verify(powerManager).wakeUp(any(), any(), any())
}
@Test
@@ -100,7 +119,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
controllerCommon.displayChip(state)
reset(windowManager)
- fakeClock.advanceTime(state.getTimeoutMs() - 1)
+ fakeClock.advanceTime(TIMEOUT_MS - 1)
verify(windowManager, never()).removeView(any())
}
@@ -111,7 +130,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
controllerCommon.displayChip(state)
reset(windowManager)
- fakeClock.advanceTime(state.getTimeoutMs() + 1)
+ fakeClock.advanceTime(TIMEOUT_MS + 1)
verify(windowManager).removeView(any())
}
@@ -128,7 +147,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
controllerCommon.displayChip(getState())
// Wait until the timeout for the first display would've happened
- fakeClock.advanceTime(state.getTimeoutMs() - waitTime + 1)
+ fakeClock.advanceTime(TIMEOUT_MS - waitTime + 1)
// Verify we didn't hide the chip
verify(windowManager, never()).removeView(any())
@@ -145,7 +164,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
controllerCommon.displayChip(getState())
// Ensure we still hide the chip eventually
- fakeClock.advanceTime(state.getTimeoutMs() + 1)
+ fakeClock.advanceTime(TIMEOUT_MS + 1)
verify(windowManager).removeView(any())
}
@@ -172,16 +191,45 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
}
@Test
- fun setIcon_viewHasIconAndContentDescription() {
+ fun setIcon_nullAppIconDrawable_iconIsFromPackageName() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(chipView, PACKAGE_NAME, appIconDrawableOverride = null, null)
+
+ assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconFromPackageName)
+ }
+
+ @Test
+ fun displayChip_hasAppIconDrawable_iconIsDrawable() {
controllerCommon.displayChip(getState())
val chipView = getChipView()
- val state = TestChipState(PACKAGE_NAME)
- controllerCommon.setIcon(state, chipView)
+ val drawable = context.getDrawable(R.drawable.ic_alarm)!!
+ controllerCommon.setIcon(chipView, PACKAGE_NAME, drawable, null)
- assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable)
- assertThat(chipView.getAppIconView().contentDescription)
- .isEqualTo(state.getAppName(context))
+ assertThat(chipView.getAppIconView().drawable).isEqualTo(drawable)
+ }
+
+ @Test
+ fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(chipView, PACKAGE_NAME, null, appNameOverride = null)
+
+ assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+ }
+
+ @Test
+ fun displayChip_hasAppName_iconContentDescriptionIsAppNameOverride() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ val appName = "Override App Name"
+ controllerCommon.setIcon(chipView, PACKAGE_NAME, null, appName)
+
+ assertThat(chipView.getAppIconView().contentDescription).isEqualTo(appName)
}
@Test
@@ -218,7 +266,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
verify(windowManager, never()).removeView(any())
}
- private fun getState() = MediaTttChipState(PACKAGE_NAME)
+ private fun getState() = ChipInfo()
private fun getChipView(): ViewGroup {
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -235,22 +283,27 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
viewUtil: ViewUtil,
@Main mainExecutor: DelayableExecutor,
tapGestureDetector: TapGestureDetector,
- ) : MediaTttChipControllerCommon<MediaTttChipState>(
+ powerManager: PowerManager
+ ) : MediaTttChipControllerCommon<ChipInfo>(
context,
logger,
windowManager,
viewUtil,
mainExecutor,
tapGestureDetector,
+ powerManager,
R.layout.media_ttt_chip
) {
- override fun updateChipView(chipState: MediaTttChipState, currentChipView: ViewGroup) {
+ override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) {
+
}
}
- inner class TestChipState(appPackageName: String?) : MediaTttChipState(appPackageName) {
- override fun getAppIcon(context: Context) = appIconDrawable
+ inner class ChipInfo : ChipInfoCommon {
+ override fun getTimeoutMs() = TIMEOUT_MS
}
}
private const val PACKAGE_NAME = "com.android.systemui"
+private const val APP_NAME = "Fake App Name"
+private const val TIMEOUT_MS = 10000L
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 56f45896436c..355d3fe4b8d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.media.MediaRoute2Info
import android.os.Handler
+import android.os.PowerManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
@@ -29,6 +30,7 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
@@ -63,6 +65,8 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
@Mock
private lateinit var logger: MediaTttLogger
@Mock
+ private lateinit var powerManager: PowerManager
+ @Mock
private lateinit var windowManager: WindowManager
@Mock
private lateinit var viewUtil: ViewUtil
@@ -70,6 +74,8 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
private lateinit var commandQueue: CommandQueue
private lateinit var commandQueueCallback: CommandQueue.Callbacks
private lateinit var fakeAppIconDrawable: Drawable
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var receiverUiEventLogger: MediaTttReceiverUiEventLogger
@Before
fun setUp() {
@@ -83,6 +89,9 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
)).thenReturn(applicationInfo)
context.setMockPackageManager(packageManager)
+ uiEventLoggerFake = UiEventLoggerFake()
+ receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+
controllerReceiver = MediaTttChipControllerReceiver(
commandQueue,
context,
@@ -91,7 +100,9 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
viewUtil,
FakeExecutor(FakeSystemClock()),
TapGestureDetector(context),
+ powerManager,
Handler.getMain(),
+ receiverUiEventLogger,
)
val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -110,6 +121,9 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
)
assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
+ )
}
@Test
@@ -122,6 +136,9 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
)
verify(windowManager, never()).addView(any(), any())
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
+ )
}
@Test
@@ -157,44 +174,6 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
verify(logger).logStateChange(any(), any())
}
- @Test
- fun displayChip_nullAppIconDrawable_iconIsFromPackageName() {
- val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, "appName")
-
- controllerReceiver.displayChip(state)
-
- assertThat(getChipView().getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
- }
-
- @Test
- fun displayChip_hasAppIconDrawable_iconIsDrawable() {
- val drawable = context.getDrawable(R.drawable.ic_alarm)!!
- val state = ChipStateReceiver(PACKAGE_NAME, drawable, "appName")
-
- controllerReceiver.displayChip(state)
-
- assertThat(getChipView().getAppIconView().drawable).isEqualTo(drawable)
- }
-
- @Test
- fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
- val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, appName = null)
-
- controllerReceiver.displayChip(state)
-
- assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(APP_NAME)
- }
-
- @Test
- fun displayChip_hasAppName_iconContentDescriptionIsAppNameOverride() {
- val appName = "Override App Name"
- val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, appName)
-
- controllerReceiver.displayChip(state)
-
- assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
- }
-
private fun getChipView(): ViewGroup {
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
verify(windowManager).addView(viewCaptor.capture(), any())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
new file mode 100644
index 000000000000..ee10ddc521f1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
@@ -0,0 +1,30 @@
+package com.android.systemui.media.taptotransfer.receiver
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class MediaTttReceiverUiEventLoggerTest : SysuiTestCase() {
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var logger: MediaTttReceiverUiEventLogger
+
+ @Before
+ fun setUp() {
+ uiEventLoggerFake = UiEventLoggerFake()
+ logger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+ }
+
+ @Test
+ fun logReceiverStateChange_eventAssociatedWithStateIsLogged() {
+ val state = ChipStateReceiver.CLOSE_TO_SENDER
+
+ logger.logReceiverStateChange(state)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index fd1d76a5d02d..ef5315428a60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.media.MediaRoute2Info
+import android.os.PowerManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
@@ -29,6 +30,7 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -65,6 +67,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Mock
private lateinit var logger: MediaTttLogger
@Mock
+ private lateinit var powerManager: PowerManager
+ @Mock
private lateinit var windowManager: WindowManager
@Mock
private lateinit var viewUtil: ViewUtil
@@ -74,6 +78,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
private lateinit var fakeAppIconDrawable: Drawable
private lateinit var fakeClock: FakeSystemClock
private lateinit var fakeExecutor: FakeExecutor
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var senderUiEventLogger: MediaTttSenderUiEventLogger
@Before
fun setUp() {
@@ -89,6 +95,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
fakeClock = FakeSystemClock()
fakeExecutor = FakeExecutor(fakeClock)
+ uiEventLoggerFake = UiEventLoggerFake()
+ senderUiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
controllerSender = MediaTttChipControllerSender(
commandQueue,
@@ -97,7 +105,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
windowManager,
viewUtil,
fakeExecutor,
- TapGestureDetector(context)
+ TapGestureDetector(context),
+ powerManager,
+ senderUiEventLogger
)
val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -113,8 +123,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(almostCloseToStartCast().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ almostCloseToStartCast().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id
+ )
}
@Test
@@ -125,8 +139,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(almostCloseToEndCast().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ almostCloseToEndCast().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id
+ )
}
@Test
@@ -137,8 +155,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToReceiverTriggered().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id
+ )
}
@Test
@@ -149,8 +171,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToThisDeviceTriggered().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id
+ )
}
@Test
@@ -161,8 +187,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToReceiverSucceeded().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToReceiverSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
+ )
}
@Test
@@ -173,8 +203,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToThisDeviceSucceeded().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToThisDeviceSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id
+ )
}
@Test
@@ -185,8 +219,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferFailed().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToReceiverFailed().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id
+ )
}
@Test
@@ -197,8 +235,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
null
)
- assertThat(getChipView().getChipText())
- .isEqualTo(transferFailed().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToThisDeviceFailed().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id
+ )
}
@Test
@@ -210,6 +252,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
)
verify(windowManager, never()).addView(any(), any())
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER.id
+ )
}
@Test
@@ -250,7 +295,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -264,7 +311,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -278,7 +327,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -292,7 +343,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -306,7 +359,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
}
@@ -355,8 +410,12 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
getChipView().getUndoButton().performClick()
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToThisDeviceTriggered().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id
+ )
}
@Test
@@ -367,7 +426,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(chipView.getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
}
@@ -416,19 +477,41 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
getChipView().getUndoButton().performClick()
- assertThat(getChipView().getChipText())
- .isEqualTo(transferToReceiverTriggered().getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id
+ )
+ }
+
+ @Test
+ fun transferToReceiverFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
+ val state = transferToReceiverFailed()
+ controllerSender.displayChip(state)
+
+ val chipView = getChipView()
+ assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
+ assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+ assertThat(getChipView().getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
+ assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
+ assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
+ assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.VISIBLE)
}
@Test
- fun transferFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
- val state = transferFailed()
+ fun transferToThisDeviceFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
+ val state = transferToThisDeviceFailed()
controllerSender.displayChip(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
- assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+ assertThat(getChipView().getChipText()).isEqualTo(
+ state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+ )
assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.VISIBLE)
@@ -475,7 +558,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun changeFromTransferTriggeredToTransferFailed_failureIconAppears() {
controllerSender.displayChip(transferToReceiverTriggered())
- controllerSender.displayChip(transferFailed())
+ controllerSender.displayChip(transferToReceiverFailed())
assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
}
@@ -498,7 +581,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
- fakeClock.advanceTime(state.getTimeoutMs() + 1)
+ fakeClock.advanceTime(state.state.timeout + 1)
verify(windowManager).removeView(any())
}
@@ -521,7 +604,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
- fakeClock.advanceTime(state.getTimeoutMs() + 1)
+ fakeClock.advanceTime(state.state.timeout + 1)
verify(windowManager).removeView(any())
}
@@ -546,34 +629,35 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
/** Helper method providing default parameters to not clutter up the tests. */
private fun almostCloseToStartCast() =
- AlmostCloseToStartCast(PACKAGE_NAME, OTHER_DEVICE_NAME)
+ ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST, routeInfo)
/** Helper method providing default parameters to not clutter up the tests. */
private fun almostCloseToEndCast() =
- AlmostCloseToEndCast(PACKAGE_NAME, OTHER_DEVICE_NAME)
+ ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_END_CAST, routeInfo)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferToReceiverTriggered() =
- TransferToReceiverTriggered(PACKAGE_NAME, OTHER_DEVICE_NAME)
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferToThisDeviceTriggered() =
- TransferToThisDeviceTriggered(PACKAGE_NAME)
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferToReceiverSucceeded(undoCallback: IUndoMediaTransferCallback? = null) =
- TransferToReceiverSucceeded(
- PACKAGE_NAME, OTHER_DEVICE_NAME, undoCallback
- )
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, undoCallback)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferToThisDeviceSucceeded(undoCallback: IUndoMediaTransferCallback? = null) =
- TransferToThisDeviceSucceeded(
- PACKAGE_NAME, OTHER_DEVICE_NAME, undoCallback
- )
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, undoCallback)
+
+ /** Helper method providing default parameters to not clutter up the tests. */
+ private fun transferToReceiverFailed() =
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo)
/** Helper method providing default parameters to not clutter up the tests. */
- private fun transferFailed() = TransferFailed(PACKAGE_NAME)
+ private fun transferToThisDeviceFailed() =
+ ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo)
}
private const val APP_NAME = "Fake app name"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
new file mode 100644
index 000000000000..263637a6b6e5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
@@ -0,0 +1,46 @@
+package com.android.systemui.media.taptotransfer.sender
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class MediaTttSenderUiEventLoggerTest : SysuiTestCase() {
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var logger: MediaTttSenderUiEventLogger
+
+ @Before
+ fun setUp () {
+ uiEventLoggerFake = UiEventLoggerFake()
+ logger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
+ }
+
+ @Test
+ fun logSenderStateChange_eventAssociatedWithStateIsLogged() {
+ val state = ChipStateSender.ALMOST_CLOSE_TO_END_CAST
+ logger.logSenderStateChange(state)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+ }
+
+ @Test
+ fun logUndoClicked_undoEventLogged() {
+ val undoEvent = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+
+ logger.logUndoClicked(undoEvent)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(undoEvent.id)
+ }
+
+ @Test
+ fun logUndoClicked_notUndoEvent_eventNotLogged() {
+ logger.logUndoClicked(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
new file mode 100644
index 000000000000..57803e874f93
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceManager
+import android.app.smartspace.SmartspaceSession
+import android.app.smartspace.SmartspaceTarget
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import android.view.ViewGroup
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dreams.smartspace.DreamsSmartspaceController
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.util.Optional
+import java.util.concurrent.Executor
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class DreamSmartspaceControllerTest : SysuiTestCase() {
+ @Mock
+ private lateinit var smartspaceManager: SmartspaceManager
+
+ @Mock
+ private lateinit var execution: Execution
+
+ @Mock
+ private lateinit var uiExecutor: Executor
+
+ @Mock
+ private lateinit var viewComponentFactory: SmartspaceViewComponent.Factory
+
+ @Mock
+ private lateinit var viewComponent: SmartspaceViewComponent
+
+ @Mock
+ private lateinit var targetFilter: SmartspaceTargetFilter
+
+ @Mock
+ private lateinit var plugin: BcSmartspaceDataPlugin
+
+ @Mock
+ private lateinit var precondition: SmartspacePrecondition
+
+ @Mock
+ private lateinit var smartspaceView: BcSmartspaceDataPlugin.SmartspaceView
+
+ @Mock
+ private lateinit var listener: BcSmartspaceDataPlugin.SmartspaceTargetListener
+
+ @Mock
+ private lateinit var session: SmartspaceSession
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ `when`(viewComponentFactory.create(any(), eq(plugin), any()))
+ .thenReturn(viewComponent)
+ `when`(viewComponent.getView()).thenReturn(smartspaceView)
+ `when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(session)
+ }
+
+ /**
+ * Ensures smartspace session begins on a listener only flow.
+ */
+ @Test
+ fun testConnectOnListen() {
+ val controller = DreamsSmartspaceController(context,
+ smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
+ Optional.of(targetFilter), Optional.of(plugin))
+
+ `when`(precondition.conditionsMet()).thenReturn(true)
+ controller.addListener(listener)
+
+ verify(smartspaceManager).createSmartspaceSession(any())
+
+ var targetListener = withArgCaptor<SmartspaceSession.OnTargetsAvailableListener> {
+ verify(session).addOnTargetsAvailableListener(any(), capture())
+ }
+
+ `when`(targetFilter.filterSmartspaceTarget(any())).thenReturn(true)
+
+ var target = Mockito.mock(SmartspaceTarget::class.java)
+ targetListener.onTargetsAvailable(listOf(target))
+
+ var targets = withArgCaptor<List<SmartspaceTarget>> {
+ verify(plugin).onTargetsAvailable(capture())
+ }
+
+ assertThat(targets.contains(target)).isTrue()
+
+ controller.removeListener(listener)
+
+ verify(session).close()
+ }
+
+ /**
+ * A class which implements SmartspaceView and extends View. This is mocked to provide the right
+ * object inheritance and interface implementation used in DreamSmartspaceController
+ */
+ private class TestView(context: Context?) : View(context),
+ BcSmartspaceDataPlugin.SmartspaceView {
+ override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
+
+ override fun setPrimaryTextColor(color: Int) {}
+
+ override fun setDozeAmount(amount: Float) {}
+
+ override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
+
+ override fun setFalsingManager(falsingManager: FalsingManager?) {}
+
+ override fun setDnd(image: Drawable?, description: String?) {}
+
+ override fun setNextAlarm(image: Drawable?, description: String?) {}
+
+ override fun setMediaTarget(target: SmartspaceTarget?) {}
+
+ override fun getSelectedPage(): Int { return 0; }
+ }
+
+ /**
+ * Ensures session begins when a view is attached.
+ */
+ @Test
+ fun testConnectOnViewCreate() {
+ val controller = DreamsSmartspaceController(context,
+ smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
+ Optional.of(targetFilter),
+ Optional.of(plugin))
+
+ `when`(precondition.conditionsMet()).thenReturn(true)
+ controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
+
+ var stateChangeListener = withArgCaptor<View.OnAttachStateChangeListener> {
+ verify(viewComponentFactory).create(any(), eq(plugin), capture())
+ }
+
+ var mockView = Mockito.mock(TestView::class.java)
+ `when`(precondition.conditionsMet()).thenReturn(true)
+ stateChangeListener.onViewAttachedToWindow(mockView)
+
+ verify(smartspaceManager).createSmartspaceSession(any())
+
+ stateChangeListener.onViewDetachedFromWindow(mockView)
+
+ verify(session).close()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
new file mode 100644
index 000000000000..d29e9a66a331
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.smartspace
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.util.concurrency.Execution
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class LockscreenPreconditionTest : SysuiTestCase() {
+ @Mock
+ private lateinit var featureFlags: FeatureFlags
+
+ @Mock
+ private lateinit var deviceProvisionedController: DeviceProvisionedController
+
+ @Mock
+ private lateinit var execution: Execution
+
+ @Mock
+ private lateinit var listener: SmartspacePrecondition.Listener
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ /**
+ * Ensures fully enabled state is published.
+ */
+ @Test
+ fun testFullyEnabled() {
+ `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+ `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+ .thenReturn(true)
+ val precondition = LockscreenPrecondition(featureFlags, deviceProvisionedController,
+ execution)
+ precondition.addListener(listener)
+
+ `verify`(listener).onCriteriaChanged()
+ assertThat(precondition.conditionsMet()).isTrue()
+ }
+
+ /**
+ * Ensures fully enabled state is published.
+ */
+ @Test
+ fun testProvisioning() {
+ `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+ `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(false)
+ `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+ .thenReturn(true)
+ val precondition =
+ LockscreenPrecondition(featureFlags, deviceProvisionedController, execution)
+ precondition.addListener(listener)
+
+ verify(listener).onCriteriaChanged()
+ assertThat(precondition.conditionsMet()).isFalse()
+
+ var argumentCaptor = ArgumentCaptor.forClass(DeviceProvisionedController
+ .DeviceProvisionedListener::class.java)
+ verify(deviceProvisionedController).addCallback(argumentCaptor.capture())
+
+ Mockito.clearInvocations(listener)
+
+ `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ argumentCaptor.value.onDeviceProvisionedChanged()
+ verify(listener).onCriteriaChanged()
+ assertThat(precondition.conditionsMet()).isTrue()
+ }
+
+ /**
+ * Makes sure user setup changes are propagated.
+ */
+ @Test
+ fun testUserSetup() {
+ `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(false)
+ `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+ .thenReturn(true)
+ val precondition =
+ LockscreenPrecondition(featureFlags, deviceProvisionedController, execution)
+ precondition.addListener(listener)
+
+ verify(listener).onCriteriaChanged()
+ assertThat(precondition.conditionsMet()).isFalse()
+
+ var argumentCaptor = ArgumentCaptor.forClass(DeviceProvisionedController
+ .DeviceProvisionedListener::class.java)
+ verify(deviceProvisionedController).addCallback(argumentCaptor.capture())
+
+ Mockito.clearInvocations(listener)
+
+ `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+ argumentCaptor.value.onUserSetupChanged()
+ verify(listener).onCriteriaChanged()
+ assertThat(precondition.conditionsMet()).isTrue()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt
new file mode 100644
index 000000000000..185a8384dd75
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt
@@ -0,0 +1,149 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceTarget
+import android.content.ContentResolver
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.smartspace.filters.LockscreenTargetFilter
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.SecureSettings
+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.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.atLeast
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.util.concurrent.Executor
+
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class LockscreenTargetFilterTest : SysuiTestCase() {
+ @Mock
+ private lateinit var secureSettings: SecureSettings
+
+ @Mock
+ private lateinit var userTracker: UserTracker
+
+ @Mock
+ private lateinit var execution: Execution
+
+ @Mock
+ private lateinit var handler: Handler
+
+ @Mock
+ private lateinit var contentResolver: ContentResolver
+
+ @Mock
+ private lateinit var uiExecution: Executor
+
+ @Mock
+ private lateinit var userHandle: UserHandle
+
+ @Mock
+ private lateinit var listener: SmartspaceTargetFilter.Listener
+
+ @Mock
+ private lateinit var lockScreenAllowPrivateNotificationsUri: Uri
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ `when`(userTracker.userHandle).thenReturn(userHandle)
+ `when`(secureSettings
+ .getUriFor(eq(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS)))
+ .thenReturn(lockScreenAllowPrivateNotificationsUri)
+ }
+
+ /**
+ * Ensures {@link Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS} is
+ * tracked.
+ */
+ @Test
+ fun testLockscreenAllowPrivateNotifications() {
+ var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+ `when`(secureSettings
+ .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+ .thenReturn(0)
+ var filter = LockscreenTargetFilter(secureSettings, userTracker, execution, handler,
+ contentResolver, uiExecution)
+
+ filter.addListener(listener)
+ var smartspaceTarget = mock(SmartspaceTarget::class.java)
+ `when`(smartspaceTarget.userHandle).thenReturn(userHandle)
+ `when`(smartspaceTarget.isSensitive).thenReturn(true)
+ assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isFalse()
+
+ var settingCaptor = ArgumentCaptor.forClass(ContentObserver::class.java)
+
+ verify(contentResolver).registerContentObserver(eq(lockScreenAllowPrivateNotificationsUri),
+ anyBoolean(), settingCaptor.capture(), anyInt())
+
+ `when`(secureSettings
+ .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+ .thenReturn(1)
+
+ clearInvocations(listener)
+ settingCaptor.value.onChange(false, mock(Uri::class.java))
+ verify(listener, atLeast(1)).onCriteriaChanged()
+ assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isTrue()
+ }
+
+ /**
+ * Ensures user switches are tracked.
+ */
+ @Test
+ fun testUserSwitchCallback() {
+ var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+ `when`(secureSettings
+ .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+ .thenReturn(0)
+ var filter = LockscreenTargetFilter(secureSettings, userTracker, execution, handler,
+ contentResolver, uiExecution)
+
+ filter.addListener(listener)
+
+ var userTrackerCallback = withArgCaptor<UserTracker.Callback> {
+ verify(userTracker).addCallback(capture(), any())
+ }
+
+ clearInvocations(listener)
+ userTrackerCallback.onUserChanged(0, context)
+
+ verify(listener).onCriteriaChanged()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 25a5b900f15a..067caa98102b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -87,6 +87,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
row = helper.createRow()
context.getOrCreateTestableResources()
.addOverride(R.bool.config_use_split_notification_shade, false)
+ context.getOrCreateTestableResources()
+ .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
transitionController = LockscreenShadeTransitionController(
statusBarStateController = statusbarStateController,
logger = logger,
@@ -247,6 +249,17 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
}
@Test
+ fun testDragDownAmount_depthDistanceIsZero_doesNotSetProgress() {
+ context.getOrCreateTestableResources()
+ .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
+ configurationController.notifyConfigurationChanged()
+
+ transitionController.dragDownAmount = 10f
+
+ verify(depthController, never()).transitionToFullShadeProgress
+ }
+
+ @Test
fun setDragDownAmount_setsValueOnMediaHierarchyManager() {
transitionController.dragDownAmount = 10f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index 353647b65cc0..4d8949562e08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -80,8 +80,8 @@ public class NotificationUiAdjustmentTest extends SysuiTestCase {
Notification.Action firstAction =
createActionBuilder("same", R.drawable.ic_corp_icon, pendingIntent).build();
Notification.Action secondAction =
- createActionBuilder("same", R.drawable.ic_account_circle, pendingIntent)
- .build();
+ createActionBuilder("same", com.android.settingslib.R.drawable.ic_account_circle,
+ pendingIntent).build();
assertThat(NotificationUiAdjustment.needReinflate(
createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt
new file mode 100644
index 000000000000..c6c043aafb20
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEvents
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.withArgCaptor
+import dagger.BindsInstance
+import dagger.Component
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+class ActivityLaunchAnimCoordinatorTest : SysuiTestCase() {
+
+ val activityLaunchEvents: NotifActivityLaunchEvents = mock()
+ val pipeline: NotifPipeline = mock()
+
+ val coordinator: ActivityLaunchAnimCoordinator =
+ DaggerTestActivityStarterCoordinatorComponent
+ .factory()
+ .create(activityLaunchEvents)
+ .coordinator
+
+ @Test
+ fun testNoLifetimeExtensionIfNoAssociatedActivityLaunch() {
+ coordinator.attach(pipeline)
+ val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+ verify(pipeline).addNotificationLifetimeExtender(capture())
+ }
+ val fakeEntry = mock<NotificationEntry>().also {
+ whenever(it.key).thenReturn("0")
+ }
+ assertFalse(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+ }
+
+ @Test
+ fun testNoLifetimeExtensionIfAssociatedActivityLaunchAlreadyEnded() {
+ coordinator.attach(pipeline)
+ val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+ verify(pipeline).addNotificationLifetimeExtender(capture())
+ }
+ val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+ verify(activityLaunchEvents).registerListener(capture())
+ }
+ val fakeEntry = mock<NotificationEntry>().also {
+ whenever(it.key).thenReturn("0")
+ }
+ eventListener.onStartLaunchNotifActivity(fakeEntry)
+ eventListener.onFinishLaunchNotifActivity(fakeEntry)
+ assertFalse(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+ }
+
+ @Test
+ fun testLifetimeExtensionWhileActivityLaunchInProgress() {
+ coordinator.attach(pipeline)
+ val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+ verify(pipeline).addNotificationLifetimeExtender(capture())
+ }
+ val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+ verify(activityLaunchEvents).registerListener(capture())
+ }
+ val onEndLifetimeExtensionCallback =
+ mock<NotifLifetimeExtender.OnEndLifetimeExtensionCallback>()
+ lifetimeExtender.setCallback(onEndLifetimeExtensionCallback)
+
+ val fakeEntry = mock<NotificationEntry>().also {
+ whenever(it.key).thenReturn("0")
+ }
+ eventListener.onStartLaunchNotifActivity(fakeEntry)
+ assertTrue(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+
+ eventListener.onFinishLaunchNotifActivity(fakeEntry)
+ verify(onEndLifetimeExtensionCallback).onEndLifetimeExtension(lifetimeExtender, fakeEntry)
+ }
+
+ @Test
+ fun testCancelLifetimeExtensionDoesNotInvokeCallback() {
+ coordinator.attach(pipeline)
+ val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+ verify(pipeline).addNotificationLifetimeExtender(capture())
+ }
+ val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+ verify(activityLaunchEvents).registerListener(capture())
+ }
+ val onEndLifetimeExtensionCallback =
+ mock<NotifLifetimeExtender.OnEndLifetimeExtensionCallback>()
+ lifetimeExtender.setCallback(onEndLifetimeExtensionCallback)
+
+ val fakeEntry = mock<NotificationEntry>().also {
+ whenever(it.key).thenReturn("0")
+ }
+ eventListener.onStartLaunchNotifActivity(fakeEntry)
+ assertTrue(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+
+ lifetimeExtender.cancelLifetimeExtension(fakeEntry)
+ eventListener.onFinishLaunchNotifActivity(fakeEntry)
+ verify(onEndLifetimeExtensionCallback, never())
+ .onEndLifetimeExtension(lifetimeExtender, fakeEntry)
+ }
+}
+
+@CoordinatorScope
+@Component(modules = [ActivityLaunchAnimCoordinatorModule::class])
+interface TestActivityStarterCoordinatorComponent {
+ val coordinator: ActivityLaunchAnimCoordinator
+
+ @Component.Factory
+ interface Factory {
+ fun create(
+ @BindsInstance activityLaunchEvents: NotifActivityLaunchEvents
+ ): TestActivityStarterCoordinatorComponent
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java
deleted file mode 100644
index 1f52b9cc4195..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.coordinator;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-
-@SmallTest
-public class CommunalCoordinatorTest extends SysuiTestCase {
- private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
- @Mock
- CommunalStateController mCommunalStateController;
- @Mock
- NotificationEntryManager mNotificationEntryManager;
- @Mock
- NotificationLockscreenUserManager mNotificationLockscreenUserManager;
- @Mock
- NotifPipeline mNotifPipeline;
- @Mock
- NotificationEntry mNotificationEntry;
- @Mock
- Pluggable.PluggableListener mFilterListener;
-
- CommunalCoordinator mCoordinator;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mCoordinator = new CommunalCoordinator(mExecutor, mNotificationEntryManager,
- mNotificationLockscreenUserManager, mCommunalStateController);
- }
-
- @Test
- public void testNotificationSuppressionInCommunal() {
- mCoordinator.attach(mNotifPipeline);
- final ArgumentCaptor<CommunalStateController.Callback> stateCallbackCaptor =
- ArgumentCaptor.forClass(CommunalStateController.Callback.class);
- verify(mCommunalStateController).addCallback(stateCallbackCaptor.capture());
-
- final CommunalStateController.Callback stateCallback = stateCallbackCaptor.getValue();
-
- final ArgumentCaptor<NotifFilter> filterCaptor =
- ArgumentCaptor.forClass(NotifFilter.class);
- verify(mNotifPipeline).addPreGroupFilter(filterCaptor.capture());
-
- final NotifFilter filter = filterCaptor.getValue();
-
- // Verify that notifications are not filtered out by default.
- assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isFalse();
-
- filter.setInvalidationListener(mFilterListener);
-
- // Verify that notifications are filtered out when communal is showing and that the filter
- // pipeline is notified.
- when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
- stateCallback.onCommunalViewShowingChanged();
- // Make sure callback depends on executor to run.
- verify(mFilterListener, never()).onPluggableInvalidated(any());
- verify(mNotificationEntryManager, never()).updateNotifications(any());
-
- mExecutor.runAllReady();
-
- verify(mFilterListener).onPluggableInvalidated(any());
- verify(mNotificationEntryManager).updateNotifications(any());
- assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isTrue();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index ee111715e5ea..6f8e5d8e514e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -41,7 +41,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
+import com.android.systemui.statusbar.phone.NotifPanelEvents;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -67,12 +67,12 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase {
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private Pluggable.PluggableListener<NotifStabilityManager> mInvalidateListener;
@Mock private HeadsUpManager mHeadsUpManager;
- @Mock private NotifPanelEventSource mNotifPanelEventSource;
+ @Mock private NotifPanelEvents mNotifPanelEvents;
@Mock private VisualStabilityProvider mVisualStabilityProvider;
@Captor private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefulnessObserverCaptor;
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mSBStateListenerCaptor;
- @Captor private ArgumentCaptor<NotifPanelEventSource.Callbacks> mNotifPanelEventsCallbackCaptor;
+ @Captor private ArgumentCaptor<NotifPanelEvents.Listener> mNotifPanelEventsCallbackCaptor;
@Captor private ArgumentCaptor<NotifStabilityManager> mNotifStabilityManagerCaptor;
private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -80,7 +80,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase {
private WakefulnessLifecycle.Observer mWakefulnessObserver;
private StatusBarStateController.StateListener mStatusBarStateListener;
- private NotifPanelEventSource.Callbacks mNotifPanelEventsCallback;
+ private NotifPanelEvents.Listener mNotifPanelEventsCallback;
private NotifStabilityManager mNotifStabilityManager;
private NotificationEntry mEntry;
@@ -92,7 +92,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase {
mFakeExecutor,
mDumpManager,
mHeadsUpManager,
- mNotifPanelEventSource,
+ mNotifPanelEvents,
mStatusBarStateController,
mVisualStabilityProvider,
mWakefulnessLifecycle);
@@ -106,7 +106,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase {
verify(mStatusBarStateController).addCallback(mSBStateListenerCaptor.capture());
mStatusBarStateListener = mSBStateListenerCaptor.getValue();
- verify(mNotifPanelEventSource).registerCallbacks(mNotifPanelEventsCallbackCaptor.capture());
+ verify(mNotifPanelEvents).registerListener(mNotifPanelEventsCallbackCaptor.capture());
mNotifPanelEventsCallback = mNotifPanelEventsCallbackCaptor.getValue();
verify(mNotifPipeline).setVisualStabilityManager(mNotifStabilityManagerCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 1561b5a5d22e..bf16e0ab39c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -69,11 +69,11 @@ import com.android.systemui.statusbar.notification.collection.render.SectionHead
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -278,18 +278,17 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mStateListenerArgumentCaptor.capture(), anyInt());
StatusBarStateController.StateListener stateListener =
mStateListenerArgumentCaptor.getValue();
- when(mNotificationStackScrollLayout.isUsingSplitNotificationShade()).thenReturn(true);
stateListener.onStateChanged(SHADE);
mController.getView().removeAllViews();
- mController.setQsExpanded(false);
+ mController.setQsFullScreen(false);
reset(mNotificationStackScrollLayout);
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ true,
/* notifVisibleInShade= */ false);
- mController.setQsExpanded(true);
+ mController.setQsFullScreen(true);
reset(mNotificationStackScrollLayout);
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
@@ -411,11 +410,11 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
boolean toShow) {
if (toShow) {
statusBarStateListener.onStateChanged(SHADE);
- mController.setQsExpanded(false);
+ mController.setQsFullScreen(false);
mController.getView().removeAllViews();
} else {
statusBarStateListener.onStateChanged(KEYGUARD);
- mController.setQsExpanded(true);
+ mController.setQsFullScreen(true);
mController.getView().addContainerView(mock(ExpandableNotificationRow.class));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 1af7035a441b..6842295ec5d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -28,7 +28,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
@@ -88,12 +87,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.CommunalSourceMonitor;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.communal.dagger.CommunalViewComponent;
import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.dump.DumpManager;
@@ -157,7 +150,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
-import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Optional;
@@ -271,21 +263,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Mock
private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
@Mock
- private CommunalViewComponent.Factory mCommunalViewComponentFactory;
- @Mock
- private CommunalViewComponent mCommunalViewComponent;
- @Mock
- private CommunalHostViewController mCommunalHostViewController;
- @Mock
- private CommunalSourceMonitor mCommunalSourceMonitor;
- @Mock
- private CommunalSource mCommunalSource;
- @Mock
- private CommunalHostView mCommunalHostView;
- @Mock
- private CommunalStateController mCommunalStateController;
- private CommunalStateController.Callback mCommunalStateControllerCallback;
- @Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock
private KeyguardStatusViewController mKeyguardStatusViewController;
@@ -361,6 +338,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
private SysUiState mSysUiState;
@Mock
private NotificationListContainer mNotificationListContainer;
+ private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -400,7 +378,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
when(mView.findViewById(R.id.notification_stack_scroller))
.thenReturn(mNotificationStackScrollLayout);
- when(mView.findViewById(R.id.communal_host)).thenReturn(mCommunalHostView);
when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
.thenReturn(mHeadsUpCallback);
@@ -466,10 +443,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
.thenReturn(mKeyguardStatusBarViewComponent);
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
.thenReturn(mKeyguardStatusBarViewController);
- when(mCommunalViewComponentFactory.build(any()))
- .thenReturn(mCommunalViewComponent);
- when(mCommunalViewComponent.getCommunalHostViewController())
- .thenReturn(mCommunalHostViewController);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
.thenReturn(mKeyguardStatusView);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
@@ -488,6 +461,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
mMainHandler = new Handler(Looper.getMainLooper());
+ mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mResources,
@@ -497,13 +471,13 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
mFalsingManager, new FalsingCollectorFake(),
mNotificationLockscreenUserManager, mNotificationEntryManager,
- mCommunalStateController, mKeyguardStateController,
+ mKeyguardStateController,
mStatusBarStateController,
mStatusBarWindowStateController,
mNotificationShadeWindowController,
mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
- mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController,
+ mMetricsLogger, mActivityManager, mConfigurationController,
() -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
mConversationNotificationManager, mMediaHiearchyManager,
mStatusBarKeyguardViewManager,
@@ -513,7 +487,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mKeyguardQsUserSwitchComponentFactory,
mKeyguardUserSwitcherComponentFactory,
mKeyguardStatusBarViewComponentFactory,
- mCommunalViewComponentFactory,
mLockscreenShadeTransitionController,
mGroupManager,
mNotificationAreaController,
@@ -546,7 +519,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mQsFrameTranslateController,
mSysUiState,
mKeyguardUnlockAnimationController,
- mNotificationListContainer);
+ mNotificationListContainer,
+ mPanelEventsEmitter);
mNotificationPanelViewController.initDependencies(
mCentralSurfaces,
() -> {},
@@ -1018,81 +992,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
verify(mKeyguardStatusViewController, never()).displayClock(LARGE, /* animate */ true);
}
- @Test
- public void testCommunalhostViewControllerInit() {
- verify(mCommunalHostViewController, times(1)).init();
- clearInvocations(mCommunalHostViewController);
- givenViewAttached();
- verify(mCommunalHostViewController, never()).init();
- }
-
- @Test
- public void testCommunalSourceListening() {
- final ArgumentCaptor<CommunalSourceMonitor.Callback> monitorCallback =
- ArgumentCaptor.forClass(CommunalSourceMonitor.Callback.class);
-
- givenViewAttached();
- verify(mCommunalSourceMonitor).addCallback(monitorCallback.capture());
-
- final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
- ArgumentCaptor.forClass(WeakReference.class);
-
- monitorCallback.getValue().onSourceAvailable(new WeakReference<>(mCommunalSource));
- mExecutor.runAllReady();
- verify(mCommunalHostViewController).show(sourceCapture.capture());
- assertThat(sourceCapture.getValue().get()).isEqualTo(mCommunalSource);
-
- clearInvocations(mCommunalHostViewController);
- givenViewDetached();
- verify(mCommunalSourceMonitor).removeCallback(any());
- }
-
- @Test
- public void testKeyguardStatusViewUpdatedWithCommunalPresence() {
- givenViewAttached();
-
- when(mResources.getBoolean(
- com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
- updateMultiUserSetting(true);
-
- ArgumentCaptor<CommunalStateController.Callback> communalCallbackCapture =
- ArgumentCaptor.forClass(CommunalStateController.Callback.class);
- verify(mCommunalStateController).addCallback(communalCallbackCapture.capture());
- final CommunalStateController.Callback communalStateControllerCallback =
- communalCallbackCapture.getValue();
-
- clearInvocations(mKeyguardStatusViewController, mKeyguardUserSwitcherController);
- // Ensure changes in communal visibility leads to setting the keyguard status view
- // visibility.
- communalStateControllerCallback.onCommunalViewShowingChanged();
- verify(mKeyguardStatusViewController).setKeyguardStatusViewVisibility(anyInt(),
- anyBoolean(), anyBoolean(), anyInt());
- verify(mKeyguardUserSwitcherController).setKeyguardUserSwitcherVisibility(anyInt(),
- anyBoolean(), anyBoolean(), anyInt());
- }
-
- @Test
- public void testCommunalAlphaUpdate() {
- // Verify keyguard content alpha changes are propagate. Note the actual value set is not
- // checked since an interpolation is applied to the incoming value.
- mNotificationPanelViewController.setKeyguardOnlyContentAlpha(0.8f);
- verify(mCommunalHostViewController).setAlpha(anyFloat());
- }
-
- @Test
- public void testCommunalPositionUpdate() {
- // Verify that the communal position is updated on interaction with the
- // NotificationPanelViewController. Note that there a number of paths where the position
- // might be updated and therefore the check isn't strictly on a single invocation.
- clearInvocations(mCommunalHostViewController);
- final View.OnLayoutChangeListener layoutChangeListener =
- mNotificationPanelViewController.createLayoutChangeListener();
- mNotificationPanelViewController.mStatusBarStateController.setState(KEYGUARD);
- layoutChangeListener.onLayoutChange(mView, 0, 0, 200, 200, 0, 0, 200, 200);
- verify(mCommunalHostViewController, atLeast(1))
- .updatePosition(anyInt(), anyBoolean());
- }
-
private void triggerPositionClockAndNotifications() {
mNotificationPanelViewController.closeQs();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
index 00af446ded3d..5fb4144bec3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
@@ -5,6 +5,7 @@ import android.testing.TestableLooper
import android.view.WindowInsets
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.SmallTest
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -40,6 +41,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
const val GESTURES_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
const val BUTTONS_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
const val NOTIFICATIONS_MARGIN = 50
+ const val SCRIM_MARGIN = 10
}
@Mock
@@ -65,12 +67,18 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ mContext.ensureTestableResources()
+ whenever(notificationsQSContainer.resources).thenReturn(mContext.resources)
notificationsQSContainerController = NotificationsQSContainerController(
notificationsQSContainer,
navigationModeController,
overviewProxyService,
featureFlags
)
+
+ mContext.orCreateTestableResources
+ .addOverride(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
+
whenever(notificationsQSContainer.defaultNotificationsMarginBottom)
.thenReturn(NOTIFICATIONS_MARGIN)
whenever(navigationModeController.addListener(navigationModeCaptor.capture()))
@@ -115,14 +123,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
given(taskbarVisible = true,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = STABLE_INSET_BOTTOM,
expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
}
@Test
@@ -153,14 +161,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
}
@Test
@@ -188,14 +196,15 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withCutout())
- then(expectedContainerPadding = CUTOUT_HEIGHT)
+ then(expectedContainerPadding = CUTOUT_HEIGHT,
+ expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withCutout().withStableBottom())
then(expectedContainerPadding = 0,
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
}
@Test
@@ -392,6 +401,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testNotificationsMarginBottomIsUpdated() {
+ Mockito.clearInvocations(notificationsQSContainer)
notificationsQSContainerController.splitShadeEnabled = true
verify(notificationsQSContainer).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index ace7415f2c17..27179fd7be92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -57,6 +57,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationClickNotifier;
@@ -130,7 +131,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private NotifPipeline mNotifPipeline;
@Mock
private NotificationVisibilityProvider mVisibilityProvider;
-
@Mock
private ActivityIntentHelper mActivityIntentHelper;
@Mock
@@ -145,14 +145,14 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private ActivityLaunchAnimator mActivityLaunchAnimator;
@Mock
private InteractionJankMonitor mJankMonitor;
+ private StatusBarNotificationActivityStarter.LaunchEventsEmitter mLaunchEventsEmitter;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
-
private NotificationTestHelper mNotificationTestHelper;
private ExpandableNotificationRow mNotificationRow;
private ExpandableNotificationRow mBubbleNotificationRow;
private final Answer<Void> mCallOnDismiss = answerVoid(
- (ActivityStarter.OnDismissAction dismissAction, Runnable cancel,
+ (OnDismissAction dismissAction, Runnable cancel,
Boolean afterKeyguardGone) -> dismissAction.onDismiss());
private ArrayList<NotificationEntry> mActiveNotifications;
@@ -201,7 +201,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
NotificationListContainer.class),
headsUpManager,
mJankMonitor);
-
+ mLaunchEventsEmitter = new StatusBarNotificationActivityStarter.LaunchEventsEmitter();
mNotificationActivityStarter =
new StatusBarNotificationActivityStarter(
getContext(),
@@ -237,12 +237,13 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mock(NotificationPresenter.class),
mock(NotificationPanelViewController.class),
mActivityLaunchAnimator,
- notificationAnimationProvider
+ notificationAnimationProvider,
+ mLaunchEventsEmitter
);
// set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
- any(ActivityStarter.OnDismissAction.class), any(), anyBoolean());
+ any(OnDismissAction.class), any(), anyBoolean());
// set up addAfterKeyguardGoneRunnable to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
@@ -402,4 +403,40 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
// THEN display should try wake up for the full screen intent
verify(mCentralSurfaces).wakeUpForFullScreenIntent();
}
+
+ @Test
+ public void testNotifActivityStarterEventSourceStartEvent_onNotificationClicked() {
+ NotifActivityLaunchEvents.Listener listener =
+ mock(NotifActivityLaunchEvents.Listener.class);
+ mLaunchEventsEmitter.registerListener(listener);
+ mNotificationActivityStarter
+ .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+ verify(listener).onStartLaunchNotifActivity(mNotificationRow.getEntry());
+ }
+
+ @Test
+ public void testNotifActivityStarterEventSourceFinishEvent_dismissKeyguardCancelled() {
+ NotifActivityLaunchEvents.Listener listener =
+ mock(NotifActivityLaunchEvents.Listener.class);
+ mLaunchEventsEmitter.registerListener(listener);
+ // set up dismissKeyguardThenExecute to synchronously invoke the cancel runnable arg
+ doAnswer(answerVoid(
+ (OnDismissAction dismissAction, Runnable cancel, Boolean afterKeyguardGone) ->
+ cancel.run()))
+ .when(mActivityStarter)
+ .dismissKeyguardThenExecute(any(OnDismissAction.class), any(), anyBoolean());
+ mNotificationActivityStarter
+ .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+ verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
+ }
+
+ @Test
+ public void testNotifActivityStarterEventSourceFinishEvent_postPanelCollapse() {
+ NotifActivityLaunchEvents.Listener listener =
+ mock(NotifActivityLaunchEvents.Listener.class);
+ mLaunchEventsEmitter.registerListener(listener);
+ mNotificationActivityStarter
+ .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+ verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index 1c48eca797a3..d30222f2b462 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -22,7 +22,6 @@ import android.app.IUidObserver
import android.app.Notification
import android.app.PendingIntent
import android.app.Person
-import android.content.Intent
import android.service.notification.NotificationListenerService.REASON_USER_STOPPED
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -460,6 +459,19 @@ class OngoingCallControllerTest : SysuiTestCase() {
.isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id)
}
+ /** Regression test for b/212467440. */
+ @Test
+ fun chipClicked_activityStarterTriggeredWithUnmodifiedIntent() {
+ val notifEntry = createOngoingCallNotifEntry()
+ val pendingIntent = notifEntry.sbn.notification.contentIntent
+ notifCollectionListener.onEntryUpdated(notifEntry)
+
+ chipView.performClick()
+
+ // Ensure that the sysui didn't modify the notification's intent -- see b/212467440.
+ verify(mockActivityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any())
+ }
+
@Test
fun notifyChipVisibilityChanged_visibleEventLogged() {
controller.notifyChipVisibilityChanged(true)
@@ -601,7 +613,6 @@ class OngoingCallControllerTest : SysuiTestCase() {
notificationEntryBuilder.modifyNotification(context).setContentIntent(null)
} else {
val contentIntent = mock(PendingIntent::class.java)
- `when`(contentIntent.intent).thenReturn(mock(Intent::class.java))
notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
index 4a579cb3fc4d..f58403d3651a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
@@ -26,7 +26,6 @@ import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.CommunalStateController
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.user.UserSwitchDialogController
@@ -55,9 +54,6 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
private lateinit var userSwitcherController: UserSwitcherController
@Mock
- private lateinit var communalStateController: CommunalStateController
-
- @Mock
private lateinit var keyguardStateController: KeyguardStateController
@Mock
@@ -99,7 +95,6 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
context.resources,
screenLifecycle,
userSwitcherController,
- communalStateController,
keyguardStateController,
falsingManager,
configurationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 896dab6c060d..91c347fc4685 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -64,7 +64,6 @@ import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
-import org.mockito.Mockito.anyString
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
@@ -207,7 +206,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userTracker.userId).thenReturn(ownerId)
`when`(userTracker.userInfo).thenReturn(ownerInfo)
- `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
+ `when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, null)
testableLooper.processAllMessages()
@@ -232,7 +231,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userTracker.userId).thenReturn(ownerId)
`when`(userTracker.userInfo).thenReturn(ownerInfo)
- `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
+ `when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, dialogShower)
testableLooper.processAllMessages()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 7726938db3b0..185942e6fbc8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -32,6 +32,7 @@ import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.wm.shell.ShellCommandHandler;
@@ -66,6 +67,7 @@ public class WMShellTest extends SysuiTestCase {
@Mock CommandQueue mCommandQueue;
@Mock ConfigurationController mConfigurationController;
+ @Mock KeyguardStateController mKeyguardStateController;
@Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock NavigationModeController mNavigationModeController;
@Mock ScreenLifecycle mScreenLifecycle;
@@ -90,9 +92,9 @@ public class WMShellTest extends SysuiTestCase {
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
Optional.of(mShellCommandHandler), Optional.of(mCompatUI),
Optional.of(mDragAndDrop),
- mCommandQueue, mConfigurationController, mKeyguardUpdateMonitor,
- mNavigationModeController, mScreenLifecycle, mSysUiState, mProtoTracer,
- mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
+ mCommandQueue, mConfigurationController, mKeyguardStateController,
+ mKeyguardUpdateMonitor, mNavigationModeController, mScreenLifecycle, mSysUiState,
+ mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
}
@Test
@@ -132,6 +134,6 @@ public class WMShellTest extends SysuiTestCase {
public void initCompatUI_registersCallbacks() {
mWMShell.initCompatUi(mCompatUI);
- verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
+ verify(mKeyguardStateController).addCallback(any(KeyguardStateController.Callback.class));
}
}
diff --git a/services/Android.bp b/services/Android.bp
index dfc88f1e359b..1e4ce19f1541 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -105,7 +105,6 @@ filegroup {
":services.selectiontoolbar-sources",
":services.smartspace-sources",
":services.speech-sources",
- ":services.startop.iorap-sources",
":services.systemcaptions-sources",
":services.translation-sources",
":services.texttospeech-sources",
@@ -162,7 +161,6 @@ java_library {
"services.selectiontoolbar",
"services.smartspace",
"services.speech",
- "services.startop",
"services.systemcaptions",
"services.translation",
"services.texttospeech",
@@ -215,7 +213,6 @@ stubs_defaults {
" --hide-annotation android.annotation.Hide" +
" --hide InternalClasses" + // com.android.* classes are okay in this interface
// TODO: remove the --hide options below
- " --hide-package com.google.android.startop.iorap" +
" --hide DeprecationMismatch" +
" --hide HiddenTypedefConstant",
visibility: ["//frameworks/base:__subpackages__"],
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 86777a2f62fd..e20b15a3e807 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -1327,14 +1327,13 @@ public class TouchExplorer extends BaseEventStreamTransformation
if (mState.isServiceDetectingGestures() && mState.isTouchInteracting()) {
// Cancel without deleting events.
mHandler.removeCallbacks(mSendHoverEnterAndMoveDelayed);
- mSendHoverEnterAndMoveDelayed.run();
- mSendHoverEnterAndMoveDelayed.clear();
- final MotionEvent prototype = mState.getLastReceivedEvent();
- final MotionEvent rawEvent = mState.getLastReceivedRawEvent();
final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
final int pointerIdBits = (1 << pointerId);
final int policyFlags = mState.getLastReceivedPolicyFlags();
- mSendHoverExitDelayed.post(prototype, rawEvent, pointerIdBits, policyFlags);
+ mSendHoverEnterAndMoveDelayed.setPointerIdBits(pointerIdBits);
+ mSendHoverEnterAndMoveDelayed.setPolicyFlags(policyFlags);
+ mSendHoverEnterAndMoveDelayed.run();
+ mSendHoverEnterAndMoveDelayed.clear();
}
}
diff --git a/services/api/current.txt b/services/api/current.txt
index 440f66aaa76b..45c00595841d 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -44,6 +44,13 @@ package com.android.server.am {
}
+package com.android.server.pm {
+
+ public interface PackageManagerLocal {
+ }
+
+}
+
package com.android.server.role {
public interface RoleServicePlatformHelper {
diff --git a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
index 21a22f44f3dd..930f49e4d117 100644
--- a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
@@ -16,6 +16,9 @@
package com.android.server.backup;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
@@ -28,7 +31,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -42,8 +44,8 @@ import com.android.internal.util.Preconditions;
import com.android.server.backup.transport.BackupTransportClient;
import com.android.server.backup.transport.OnTransportRegisteredListener;
import com.android.server.backup.transport.TransportConnection;
-import com.android.server.backup.transport.TransportConnectionManager;
import com.android.server.backup.transport.TransportConnectionListener;
+import com.android.server.backup.transport.TransportConnectionManager;
import com.android.server.backup.transport.TransportNotAvailableException;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.backup.transport.TransportStats;
@@ -58,6 +60,7 @@ import java.util.function.Predicate;
/** Handles in-memory bookkeeping of all BackupTransport objects. */
public class TransportManager {
private static final String TAG = "BackupTransportManager";
+ private static final boolean MORE_DEBUG = false;
@VisibleForTesting
public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
@@ -130,14 +133,61 @@ public class TransportManager {
}
}
+ void onPackageEnabled(String packageName) {
+ onPackageAdded(packageName);
+ }
+
+ void onPackageDisabled(String packageName) {
+ onPackageRemoved(packageName);
+ }
+
@WorkerThread
void onPackageChanged(String packageName, String... components) {
+ // Determine if the overall package has changed and not just its
+ // components - see {@link EXTRA_CHANGED_COMPONENT_NAME_LIST}. When we
+ // know a package was enabled/disabled we'll handle that directly and
+ // not continue with onPackageChanged.
+ if (components.length == 1 && components[0].equals(packageName)) {
+ int enabled;
+ try {
+ enabled = mPackageManager.getApplicationEnabledSetting(packageName);
+ } catch (IllegalArgumentException ex) {
+ // packageName doesn't exist: likely due to a race with it being uninstalled.
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + packageName + " was changed, but no longer exists.");
+ }
+ return;
+ }
+ switch (enabled) {
+ case COMPONENT_ENABLED_STATE_ENABLED: {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + packageName + " was enabled.");
+ }
+ onPackageEnabled(packageName);
+ return;
+ }
+ case COMPONENT_ENABLED_STATE_DISABLED: {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + packageName + " was disabled.");
+ }
+ onPackageDisabled(packageName);
+ return;
+ }
+ default: {
+ Slog.w(TAG, "Package " + packageName + " enabled setting: " + enabled);
+ return;
+ }
+ }
+ }
// Unfortunately this can't be atomic because we risk a deadlock if
// registerTransportsFromPackage() is put inside the synchronized block
Set<ComponentName> transportComponents = new ArraySet<>(components.length);
for (String componentName : components) {
transportComponents.add(new ComponentName(packageName, componentName));
}
+ if (transportComponents.isEmpty()) {
+ return;
+ }
synchronized (mTransportLock) {
mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains);
}
diff --git a/services/companion/TEST_MAPPING b/services/companion/TEST_MAPPING
index 4a37cb812981..38d937288569 100644
--- a/services/companion/TEST_MAPPING
+++ b/services/companion/TEST_MAPPING
@@ -7,6 +7,9 @@
"name": "CtsCompanionDeviceManagerUiAutomationTestCases"
},
{
+ "name": "CtsCompanionDeviceManagerNoCompanionServicesTestCases"
+ },
+ {
"name": "CtsOsTestCases",
"options": [
{
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index c9d704084c19..2068e6d380b7 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -45,6 +45,7 @@ import android.util.SparseArray;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.pm.PackageList;
import com.android.server.pm.PackageSetting;
+import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageApi;
import com.android.server.pm.pkg.PackageState;
@@ -68,6 +69,7 @@ import java.util.function.Consumer;
* @hide Only for use within the system server.
*/
public abstract class PackageManagerInternal {
+
@IntDef(prefix = "PACKAGE_", value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -902,6 +904,11 @@ public abstract class PackageManagerInternal {
public abstract void freeStorage(String volumeUuid, long bytes,
@StorageManager.AllocateFlags int flags) throws IOException;
+ /**
+ * Blocking call to clear all cached app data above quota.
+ */
+ public abstract void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException;
+
/** Returns {@code true} if the specified component is enabled and matches the given flags. */
public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component,
@PackageManager.ComponentInfoFlagsBits long flags, int userId);
@@ -1362,4 +1369,8 @@ public abstract class PackageManagerInternal {
*/
@NonNull
public abstract PackageDataSnapshot snapshot();
+
+ public abstract void shutdown();
+
+ public abstract DynamicCodeLogger getDynamicCodeLogger();
}
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index 1e534b7c1515..186ff6215c9c 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.timedetector.NetworkTimeSuggestion;
@@ -45,12 +46,12 @@ import android.util.LocalLog;
import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.NtpTrustedTime.TimeResult;
-import android.util.TimeUtils;
import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.time.Duration;
/**
* Monitors the network time. If looking up the network time fails for some reason, it tries a few
@@ -191,6 +192,19 @@ public class NetworkTimeUpdateService extends Binder {
return success;
}
+ /**
+ * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+ * test value, i.e. so the normal value will be used next time.
+ */
+ void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.SET_TIME, "set NTP server config for tests");
+
+ mLocalLog.log("Setting server config for tests: hostname=" + hostname
+ + ", timeout=" + timeout);
+ mTime.setServerConfigForTests(hostname, timeout);
+ }
+
private void onPollNetworkTime(int event) {
// If we don't have any default network, don't bother.
if (mDefaultNetwork == null) return;
@@ -349,17 +363,14 @@ public class NetworkTimeUpdateService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- pw.print("PollingIntervalMs: ");
- TimeUtils.formatDuration(mPollingIntervalMs, pw);
- pw.print("\nPollingIntervalShorterMs: ");
- TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
- pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
- pw.println("\nTryAgainCounter: " + mTryAgainCounter);
- NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
- pw.println("NTP cache result: " + ntpResult);
- if (ntpResult != null) {
- pw.println("NTP result age: " + ntpResult.getAgeMillis());
- }
+ pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
+ pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
+ pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+ pw.println("mTryAgainCounter=" + mTryAgainCounter);
+ pw.println();
+ pw.println("NtpTrustedTime:");
+ mTime.dump(pw);
+ pw.println();
pw.println("Local logs:");
mLocalLog.dump(fd, pw, args);
pw.println();
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
index dc93023d82c5..464af01a009a 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.os.ShellCommand;
import java.io.PrintWriter;
+import java.time.Duration;
import java.util.Objects;
/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
@@ -40,6 +41,13 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
*/
private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
+ /**
+ * A shell command that sets the NTP server config for tests. Config is cleared on reboot.
+ */
+ private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
+ private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
+ private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
+
@NonNull
private final NetworkTimeUpdateService mNetworkTimeUpdateService;
@@ -58,6 +66,8 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
return runClearTime();
case SHELL_COMMAND_FORCE_REFRESH:
return runForceRefresh();
+ case SHELL_COMMAND_SET_SERVER_CONFIG:
+ return runSetServerConfig();
default: {
return handleDefaultCommands(cmd);
}
@@ -75,6 +85,29 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
return 0;
}
+ private int runSetServerConfig() {
+ String hostname = null;
+ Duration timeout = null;
+ String opt;
+ while ((opt = getNextArg()) != null) {
+ switch (opt) {
+ case SET_SERVER_CONFIG_HOSTNAME_ARG: {
+ hostname = getNextArgRequired();
+ break;
+ }
+ case SET_SERVER_CONFIG_TIMEOUT_ARG: {
+ timeout = Duration.ofMillis(Integer.parseInt(getNextArgRequired()));
+ break;
+ }
+ default: {
+ throw new IllegalArgumentException("Unknown option: " + opt);
+ }
+ }
+ }
+ mNetworkTimeUpdateService.setServerConfigForTests(hostname, timeout);
+ return 0;
+ }
+
@Override
public void onHelp() {
final PrintWriter pw = getOutPrintWriter();
@@ -85,6 +118,12 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
pw.printf(" Clears the latest time.\n");
pw.printf(" %s\n", SHELL_COMMAND_FORCE_REFRESH);
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
+ pw.printf(" %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
+ pw.printf(" Sets the NTP server config for tests. The config is not persisted.\n");
+ pw.printf(" Options: [%s <hostname>] [%s <millis>]\n",
+ SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_TIMEOUT_ARG);
+ pw.printf(" Each key/value is optional and must be specified to override the\n");
+ pw.printf(" normal value, not specifying a key causes it to reset to the original.\n");
pw.println();
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d4764a61566e..4628a1ff073b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -176,9 +176,6 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -198,10 +195,6 @@ import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
/**
* Service responsible for various storage media. Connects to {@code vold} to
* watch for and manage dynamically added storage, such as SD cards and USB mass
@@ -3130,8 +3123,8 @@ class StorageManagerService extends IStorageManager.Stub
}
@Override
- public void mountObb(String rawPath, String canonicalPath, String key,
- IObbActionListener token, int nonce, ObbInfo obbInfo) {
+ public void mountObb(String rawPath, String canonicalPath, IObbActionListener token,
+ int nonce, ObbInfo obbInfo) {
Objects.requireNonNull(rawPath, "rawPath cannot be null");
Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
Objects.requireNonNull(token, "token cannot be null");
@@ -3140,7 +3133,7 @@ class StorageManagerService extends IStorageManager.Stub
final int callingUid = Binder.getCallingUid();
final ObbState obbState = new ObbState(rawPath, canonicalPath,
callingUid, token, nonce, null);
- final ObbAction action = new MountObbAction(obbState, key, callingUid, obbInfo);
+ final ObbAction action = new MountObbAction(obbState, callingUid, obbInfo);
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
if (DEBUG_OBB)
@@ -3677,11 +3670,20 @@ class StorageManagerService extends IStorageManager.Stub
mInstaller.tryMountDataMirror(volumeUuid);
}
}
- } catch (RemoteException | Installer.InstallerException e) {
+ } catch (Exception e) {
Slog.wtf(TAG, e);
// Make sure to re-throw this exception; we must not ignore failure
// to prepare the user storage as it could indicate that encryption
// wasn't successfully set up.
+ //
+ // Very unfortunately, these errors need to be ignored for broken
+ // users that already existed on-disk from older Android versions.
+ UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
+ if (umInternal.shouldIgnorePrepareStorageErrors(userId)) {
+ Slog.wtf(TAG, "ignoring error preparing storage for existing user " + userId
+ + "; device may be insecure!");
+ return;
+ }
throw new RuntimeException(e);
}
}
@@ -4586,13 +4588,11 @@ class StorageManagerService extends IStorageManager.Stub
}
class MountObbAction extends ObbAction {
- private final String mKey;
private final int mCallingUid;
private ObbInfo mObbInfo;
- MountObbAction(ObbState obbState, String key, int callingUid, ObbInfo obbInfo) {
+ MountObbAction(ObbState obbState, int callingUid, ObbInfo obbInfo) {
super(obbState);
- mKey = key;
mCallingUid = callingUid;
mObbInfo = obbInfo;
}
@@ -4615,29 +4615,8 @@ class StorageManagerService extends IStorageManager.Stub
"Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
}
- final String hashedKey;
- final String binderKey;
- if (mKey == null) {
- hashedKey = "none";
- binderKey = "";
- } else {
- try {
- SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-
- KeySpec ks = new PBEKeySpec(mKey.toCharArray(), mObbInfo.salt,
- PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
- SecretKey key = factory.generateSecret(ks);
- BigInteger bi = new BigInteger(key.getEncoded());
- hashedKey = bi.toString(16);
- binderKey = hashedKey;
- } catch (GeneralSecurityException e) {
- throw new ObbException(ERROR_INTERNAL, e);
- }
- }
-
try {
- mObbState.volId = mVold.createObb(mObbState.canonicalPath, binderKey,
- mObbState.ownerGid);
+ mObbState.volId = mVold.createObb(mObbState.canonicalPath, mObbState.ownerGid);
mVold.mount(mObbState.volId, 0, -1, null);
if (DEBUG_OBB)
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 5fe87199f1b8..18e0155cfd34 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -650,6 +650,38 @@ final class ActivityManagerConstants extends ContentObserver {
// initialized in the constructor.
public int CUR_MAX_EMPTY_PROCESSES;
+
+ /** @see #mNoKillCachedProcessesUntilBootCompleted */
+ private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED =
+ "no_kill_cached_processes_until_boot_completed";
+
+ /** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
+ private static final String KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS =
+ "no_kill_cached_processes_post_boot_completed_duration_millis";
+
+ /** @see #mNoKillCachedProcessesUntilBootCompleted */
+ private static final boolean DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = false;
+
+ /** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
+ private static final long
+ DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = 0;
+
+ /**
+ * If true, do not kill excessive cached processes proactively, until user-0 is unlocked.
+ * @see #mNoKillCachedProcessesPostBootCompletedDurationMillis
+ */
+ volatile boolean mNoKillCachedProcessesUntilBootCompleted =
+ DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED;
+
+ /**
+ * Do not kill excessive cached processes proactively, for this duration after each user is
+ * unlocked.
+ * Note we don't proactively kill extra cached processes after this. The next oomadjuster pass
+ * will naturally do it.
+ */
+ volatile long mNoKillCachedProcessesPostBootCompletedDurationMillis =
+ DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS;
+
// The number of empty apps at which we don't consider it necessary to do
// memory trimming.
public int CUR_TRIM_EMPTY_PROCESSES = computeEmptyProcessLimit(MAX_CACHED_PROCESSES) / 2;
@@ -659,6 +691,14 @@ final class ActivityManagerConstants extends ContentObserver {
public int CUR_TRIM_CACHED_PROCESSES =
(MAX_CACHED_PROCESSES - computeEmptyProcessLimit(MAX_CACHED_PROCESSES)) / 3;
+ /** @see #mNoKillCachedProcessesUntilBootCompleted */
+ private static final String KEY_MAX_EMPTY_TIME_MILLIS =
+ "max_empty_time_millis";
+
+ private static final long DEFAULT_MAX_EMPTY_TIME_MILLIS = 30 * 60 * 1000;
+
+ volatile long mMaxEmptyTimeMillis = DEFAULT_MAX_EMPTY_TIME_MILLIS;
+
/**
* Packages that can't be killed even if it's requested to be killed on imperceptible.
*/
@@ -869,6 +909,15 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_DEFER_BOOT_COMPLETED_BROADCAST:
updateDeferBootCompletedBroadcast();
break;
+ case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED:
+ updateNoKillCachedProcessesUntilBootCompleted();
+ break;
+ case KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS:
+ updateNoKillCachedProcessesPostBootCompletedDurationMillis();
+ break;
+ case KEY_MAX_EMPTY_TIME_MILLIS:
+ updateMaxEmptyTimeMillis();
+ break;
default:
break;
}
@@ -1288,6 +1337,27 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST);
}
+ private void updateNoKillCachedProcessesUntilBootCompleted() {
+ mNoKillCachedProcessesUntilBootCompleted = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED,
+ DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
+ }
+
+ private void updateNoKillCachedProcessesPostBootCompletedDurationMillis() {
+ mNoKillCachedProcessesPostBootCompletedDurationMillis = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS,
+ DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
+ }
+
+ private void updateMaxEmptyTimeMillis() {
+ mMaxEmptyTimeMillis = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_MAX_EMPTY_TIME_MILLIS,
+ DEFAULT_MAX_EMPTY_TIME_MILLIS);
+ }
+
private long[] parseLongArray(@NonNull String key, @NonNull long[] def) {
final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
key, null);
@@ -1562,6 +1632,12 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mComponentAliasOverrides);
pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST);
pw.print("="); pw.println(mDeferBootCompletedBroadcast);
+ pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
+ pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted);
+ pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
+ pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis);
+ pw.print(" "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS);
+ pw.print("="); pw.println(mMaxEmptyTimeMillis);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 47f9fd535801..670809f1d947 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -79,6 +79,7 @@ import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
import static android.os.Process.ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS;
import static android.os.Process.ZYGOTE_PROCESS;
import static android.os.Process.getTotalMemory;
+import static android.os.Process.isSdkSandboxUid;
import static android.os.Process.isThreadInProcess;
import static android.os.Process.killProcess;
import static android.os.Process.killProcessQuiet;
@@ -8561,6 +8562,9 @@ public class ActivityManagerService extends IActivityManager.Stub
if (process.info.isInstantApp()) {
sb.append("Instant-App: true\n");
}
+ if (isSdkSandboxUid(process.uid)) {
+ sb.append("SdkSandbox: true\n");
+ }
}
}
@@ -16998,7 +17002,17 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void addPendingTopUid(int uid, int pid) {
- mPendingStartActivityUids.add(uid, pid);
+ final boolean isNewPending = mPendingStartActivityUids.add(uid, pid);
+ // If the next top activity is in cached and frozen mode, WM should raise its priority
+ // to unfreeze it. This is done by calling AMS.updateOomAdj that will lower its oom adj.
+ // However, WM cannot hold the AMS clock here so the updateOomAdj operation is performed
+ // in a separate thread asynchronously. Therefore WM can't guarantee AMS will unfreeze
+ // next top activity on time. This race will fail the following binder transactions WM
+ // sends to the activity. After this race issue between WM/ATMS and AMS is solved, this
+ // workaround can be removed. (b/213288355)
+ if (isNewPending && mOomAdjuster != null) { // It can be null in unit test.
+ mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index fc29982dc7f0..d84c1fcd54fb 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -1002,6 +1002,7 @@ public final class AppExitInfoTracker {
info.setPackageName(app.info.packageName);
info.setPackageList(app.getPackageList());
info.setReason(ApplicationExitInfo.REASON_UNKNOWN);
+ info.setSubReason(ApplicationExitInfo.SUBREASON_UNKNOWN);
info.setStatus(0);
info.setImportance(procStateToImportance(app.mState.getReportedProcState()));
info.setPss(app.mProfile.getLastPss());
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index b18d390476f0..ff569a681a4e 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -183,6 +183,8 @@ public final class CachedAppOptimizer {
private final ActivityManagerGlobalLock mProcLock;
+ private final Object mFreezerLock = new Object();
+
private final OnPropertiesChangedListener mOnFlagsChangedListener =
new OnPropertiesChangedListener() {
@Override
@@ -949,8 +951,8 @@ public final class CachedAppOptimizer {
}
}
- @GuardedBy({"mAm", "mProcLock"})
- void unfreezeAppLSP(ProcessRecord app) {
+ @GuardedBy({"mAm", "mProcLock", "mFreezerLock"})
+ void unfreezeAppInternalLSP(ProcessRecord app) {
final int pid = app.getPid();
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
if (opt.isPendingFreeze()) {
@@ -1035,6 +1037,42 @@ public final class CachedAppOptimizer {
}
}
+ @GuardedBy({"mAm", "mProcLock"})
+ void unfreezeAppLSP(ProcessRecord app) {
+ synchronized (mFreezerLock) {
+ unfreezeAppInternalLSP(app);
+ }
+ }
+
+ /**
+ * This quick function works around the race condition between WM/ATMS and AMS, allowing
+ * the former to directly unfreeze a frozen process before the latter runs updateOomAdj.
+ * After the race issue is solved, this workaround can be removed. (b/213288355)
+ * The caller of this function should still trigger updateOomAdj for AMS to unfreeze the app.
+ * @param pid pid of the process to be unfrozen
+ */
+ void unfreezeProcess(int pid) {
+ synchronized (mFreezerLock) {
+ ProcessRecord app = mFrozenProcesses.get(pid);
+ if (app == null) {
+ return;
+ }
+ Slog.d(TAG_AM, "quick sync unfreeze " + pid);
+ try {
+ freezeBinder(pid, false);
+ } catch (RuntimeException e) {
+ Slog.e(TAG_AM, "Unable to quick unfreeze binder for " + pid);
+ return;
+ }
+
+ try {
+ Process.setProcessFrozen(pid, app.uid, false);
+ } catch (Exception e) {
+ Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
+ }
+ }
+ }
+
/**
* To be called when the given app is killed.
*/
@@ -1464,8 +1502,6 @@ public final class CachedAppOptimizer {
return;
}
- Slog.d(TAG_AM, "froze " + pid + " " + name);
-
EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);
// See above for why we're not taking mPhenotypeFlagLock here
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 6a211d31aa49..e0d333ee8f6a 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -750,7 +750,7 @@ public class OomAdjuster {
}
final long now = SystemClock.uptimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
- final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
+ final long oldTime = now - mConstants.mMaxEmptyTimeMillis;
final boolean fullUpdate = processes == null;
ActiveUids activeUids = uids;
ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP()
@@ -1031,15 +1031,25 @@ public class OomAdjuster {
}
}
+ private long mNextNoKillDebugMessageTime;
+
@GuardedBy({"mService", "mProcLock"})
private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
final long oldTime, final ActiveUids activeUids) {
ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
final int numLru = lruList.size();
- final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
- final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
- - emptyProcessLimit;
+ final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
+ if (!doKillExcessiveProcesses) {
+ if (mNextNoKillDebugMessageTime < now) {
+ Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734
+ mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds
+ }
+ }
+ final int emptyProcessLimit = doKillExcessiveProcesses
+ ? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE;
+ final int cachedProcessLimit = doKillExcessiveProcesses
+ ? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE;
int lastCachedGroup = 0;
int lastCachedGroupUid = 0;
int numCached = 0;
@@ -1089,7 +1099,7 @@ public class OomAdjuster {
case PROCESS_STATE_CACHED_EMPTY:
if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.getLastActivityTime() < oldTime) {
- app.killLocked("empty for " + ((oldTime + ProcessList.MAX_EMPTY_TIME
+ app.killLocked("empty for " + ((now
- app.getLastActivityTime()) / 1000) + "s",
"empty for too long",
ApplicationExitInfo.REASON_OTHER,
@@ -1258,6 +1268,25 @@ public class OomAdjuster {
}
}
+ /**
+ * Return true if we should kill excessive cached/empty processes.
+ */
+ private boolean shouldKillExcessiveProcesses(long nowUptime) {
+ final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime();
+
+ if (lastUserUnlockingUptime == 0) {
+ // No users have been unlocked.
+ return !mConstants.mNoKillCachedProcessesUntilBootCompleted;
+ }
+ final long noKillCachedProcessesPostBootCompletedDurationMillis =
+ mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis;
+ if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis)
+ > nowUptime) {
+ return false;
+ }
+ return true;
+ }
+
private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
new ComputeOomAdjWindowCallback();
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index b1c91ba4a79d..81a8680cdbf0 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -368,8 +368,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
// Apply any launch flags from the ActivityOptions. This is to ensure that the caller
// can specify a consistent launch mode even if the PendingIntent is immutable
- final ActivityOptions opts = options != null ? ActivityOptions.fromBundle(options)
- : null;
+ final ActivityOptions opts = ActivityOptions.fromBundle(options);
if (opts != null) {
finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
}
diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java
index 802ea001e28c..455c75b88218 100644
--- a/services/core/java/com/android/server/am/PendingStartActivityUids.java
+++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java
@@ -46,10 +46,13 @@ final class PendingStartActivityUids {
mContext = context;
}
- synchronized void add(int uid, int pid) {
+ /** Returns {@code true} if the uid is put to the pending array. Otherwise it existed. */
+ synchronized boolean add(int uid, int pid) {
if (mPendingUids.get(uid) == null) {
mPendingUids.put(uid, new Pair<>(pid, SystemClock.elapsedRealtime()));
+ return true;
}
+ return false;
}
synchronized void delete(int uid) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index e7a67fd8ef4e..48ca59dc4c64 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -293,9 +293,6 @@ public final class ProcessList {
// without empty apps being able to push them out of memory.
static final int MIN_CACHED_APPS = 2;
- // We allow empty processes to stick around for at most 30 minutes.
- static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
-
// Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_CRITICAL_THRESHOLD = 3;
@@ -1893,7 +1890,7 @@ public final class ProcessList {
/** Return true if the client app for the SDK sandbox process is debuggable. */
private boolean isAppForSdkSandboxDebuggable(ProcessRecord sandboxProcess) {
// TODO (b/221004701) use client app process name
- final int appUid = Process.toAppUid(sandboxProcess.uid);
+ final int appUid = Process.getAppUidForSdkSandboxUid(sandboxProcess.uid);
IPackageManager pm = mService.getPackageManager();
try {
String[] packages = pm.getPackagesForUid(appUid);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 1095cf0a0d30..ad176556ba65 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -399,6 +399,9 @@ class UserController implements Handler.Callback {
@GuardedBy("mLock")
private @StopUserOnSwitch int mStopUserOnSwitch = STOP_USER_ON_SWITCH_DEFAULT;
+ /** @see #getLastUserUnlockingUptime */
+ private volatile long mLastUserUnlockingUptime = 0;
+
UserController(ActivityManagerService service) {
this(new Injector(service));
}
@@ -661,6 +664,8 @@ class UserController implements Handler.Callback {
uss.mUnlockProgress.setProgress(20);
+ mLastUserUnlockingUptime = SystemClock.uptimeMillis();
+
// Dispatch unlocked to system services; when fully dispatched,
// that calls through to the next "unlocked" phase
mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
@@ -2753,6 +2758,7 @@ class UserController implements Handler.Callback {
if (mSwitchingToSystemUserMessage != null) {
pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage);
}
+ pw.println(" mLastUserUnlockingUptime:" + mLastUserUnlockingUptime);
}
}
@@ -3078,6 +3084,14 @@ class UserController implements Handler.Callback {
}
/**
+ * Uptime when any user was being unlocked most recently. 0 if no users have been unlocked
+ * yet. To avoid lock contention (since it's used by OomAdjuster), it's volatile internally.
+ */
+ public long getLastUserUnlockingUptime() {
+ return mLastUserUnlockingUptime;
+ }
+
+ /**
* Helper class to store user journey and session id.
*
* <p> User journey tracks a chain of user lifecycle events occurring during different user
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 16d83ec729b9..7a6603d1f243 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -91,8 +91,8 @@ class UserSwitchingDialog extends AlertDialog
setCancelable(false);
Resources res = getContext().getResources();
// Custom view due to alignment and font size requirements
- View view = LayoutInflater.from(getContext()).inflate(R.layout.user_switching_dialog,
- null);
+ TextView view = (TextView) LayoutInflater.from(getContext()).inflate(
+ R.layout.user_switching_dialog, null);
String viewMessage = null;
if (UserManager.isSplitSystemUser() && mNewUser.id == UserHandle.USER_SYSTEM) {
@@ -115,9 +115,12 @@ class UserSwitchingDialog extends AlertDialog
if (viewMessage == null) {
viewMessage = res.getString(R.string.user_switching_message, mNewUser.name);
}
+
+ view.setCompoundDrawablesWithIntrinsicBounds(null,
+ getContext().getDrawable(R.drawable.ic_swap_horiz), null, null);
}
view.setAccessibilityPaneTitle(viewMessage);
- ((TextView) view.findViewById(R.id.message)).setText(viewMessage);
+ view.setText(viewMessage);
setView(view);
}
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 3efd8ad0581b..4fa1ba1c8158 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -359,6 +359,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
public enum FrameRate {
FPS_DEFAULT(0),
FPS_30(30),
+ FPS_40(40),
FPS_45(45),
FPS_60(60),
FPS_90(90),
@@ -378,6 +379,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
switch (raw) {
case "30":
return FrameRate.FPS_30.fps;
+ case "40":
+ return FrameRate.FPS_40.fps;
case "45":
return FrameRate.FPS_45.fps;
case "60":
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 82476d8d1df8..d01be5820d34 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -127,6 +127,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HwBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -10471,6 +10472,25 @@ public class AudioService extends IAudioService.Stub
return mMediaFocusControl.sendFocusLoss(focusLoser);
}
+ private static final String[] HAL_VERSIONS = new String[] {"7.1", "7.0", "6.0", "4.0", "2.0"};
+
+ /** @see AudioManager#getHalVersion */
+ public @Nullable String getHalVersion() {
+ for (String version : HAL_VERSIONS) {
+ try {
+ HwBinder.getService(
+ String.format("android.hardware.audio@%s::IDevicesFactory", version),
+ "default");
+ return version;
+ } catch (NoSuchElementException e) {
+ // Ignore, the specified HAL interface is not found.
+ } catch (RemoteException re) {
+ Log.e(TAG, "Remote exception when getting hardware audio service:", re);
+ }
+ }
+ return null;
+ }
+
/** see AudioManager.hasRegisteredDynamicPolicy */
public boolean hasRegisteredDynamicPolicy() {
synchronized (mAudioPolicies) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 653776b3ca65..79e3bf53acd3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -140,12 +140,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
- // For UDFPS, notify SysUI that the illumination can be turned off.
- // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
- if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
- mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
- }
-
+ // For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
+ // for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
+ mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
super.onAcquired(acquiredInfo, vendorCode);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index c92d599d68e6..bb1fed0bfecc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -114,12 +114,16 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
@Override
public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
+ boolean acquiredGood =
+ acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
// For UDFPS, notify SysUI that the illumination can be turned off.
// See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
- if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD
- && mSensorProps.isAnyUdfpsType()) {
- vibrateSuccess();
- mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
+ if (mSensorProps.isAnyUdfpsType()) {
+ if (acquiredGood) {
+ vibrateSuccess();
+ }
+ mSensorOverlays.ifUdfps(
+ controller -> controller.onAcquired(getSensorId(), acquiredInfo));
}
mSensorOverlays.ifUdfps(controller -> {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index e0b768d7c592..ecb43f601a86 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -467,7 +467,8 @@ public class CameraServiceProxy extends SystemService
ParceledListSlice<ActivityManager.RecentTaskInfo> recentTasks = null;
try {
- recentTasks = ActivityTaskManager.getService().getRecentTasks(/*maxNum*/1,
+ // Get 2 recent tasks in case we are running in split mode
+ recentTasks = ActivityTaskManager.getService().getRecentTasks(/*maxNum*/2,
/*flags*/ 0, userId);
} catch (RemoteException e) {
Log.e(TAG, "Failed to query recent tasks!");
@@ -475,23 +476,27 @@ public class CameraServiceProxy extends SystemService
}
if ((recentTasks != null) && (!recentTasks.getList().isEmpty())) {
- ActivityManager.RecentTaskInfo task = recentTasks.getList().get(0);
- if (packageName.equals(task.topActivityInfo.packageName)) {
- taskInfo = new TaskInfo();
- taskInfo.frontTaskId = task.taskId;
- taskInfo.isResizeable =
- (task.topActivityInfo.resizeMode != RESIZE_MODE_UNRESIZEABLE);
- taskInfo.displayId = task.displayId;
- taskInfo.userId = task.userId;
- taskInfo.isFixedOrientationLandscape =
- ActivityInfo.isFixedOrientationLandscape(
- task.topActivityInfo.screenOrientation);
- taskInfo.isFixedOrientationPortrait =
- ActivityInfo.isFixedOrientationPortrait(
- task.topActivityInfo.screenOrientation);
- } else {
- Log.e(TAG, "Recent task package name: " + task.topActivityInfo.packageName
- + " doesn't match with camera client package name: " + packageName);
+ for (ActivityManager.RecentTaskInfo task : recentTasks.getList()) {
+ if (packageName.equals(task.topActivityInfo.packageName)) {
+ taskInfo = new TaskInfo();
+ taskInfo.frontTaskId = task.taskId;
+ taskInfo.isResizeable =
+ (task.topActivityInfo.resizeMode != RESIZE_MODE_UNRESIZEABLE);
+ taskInfo.displayId = task.displayId;
+ taskInfo.userId = task.userId;
+ taskInfo.isFixedOrientationLandscape =
+ ActivityInfo.isFixedOrientationLandscape(
+ task.topActivityInfo.screenOrientation);
+ taskInfo.isFixedOrientationPortrait =
+ ActivityInfo.isFixedOrientationPortrait(
+ task.topActivityInfo.screenOrientation);
+ break;
+ }
+ }
+
+ if (taskInfo == null) {
+ Log.e(TAG, "Recent tasks don't include camera client package name: " +
+ packageName);
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
}
} else {
diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
index 62b701aff398..28c7cad3b184 100644
--- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
+++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
@@ -18,6 +18,7 @@ package com.android.server.clipboard;
import android.annotation.Nullable;
import android.content.ClipData;
+import android.os.SystemProperties;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -39,6 +40,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
private static final String PIPE_NAME = "pipe:clipboard";
private static final int HOST_PORT = 5000;
private final Thread mHostMonitorThread;
+ private static final boolean LOG_CLIBOARD_ACCESS =
+ SystemProperties.getBoolean("ro.boot.qemu.log_clipboard_access", false);
private FileDescriptor mPipe = null;
private static byte[] createOpenHandshake() {
@@ -51,8 +54,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
return bits;
}
- private boolean isPipeOpened() {
- return mPipe != null;
+ private synchronized FileDescriptor getPipeFD() {
+ return mPipe;
}
private synchronized boolean openPipe() {
@@ -104,14 +107,16 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
return msg;
}
- private void sendMessage(final byte[] msg) throws ErrnoException, InterruptedIOException {
+ private static void sendMessage(
+ final FileDescriptor fd,
+ final byte[] msg) throws ErrnoException, InterruptedIOException {
final byte[] lengthBits = new byte[4];
final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(msg.length);
- Os.write(mPipe, lengthBits, 0, lengthBits.length);
- Os.write(mPipe, msg, 0, msg.length);
+ Os.write(fd, lengthBits, 0, lengthBits.length);
+ Os.write(fd, msg, 0, msg.length);
}
EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) {
@@ -132,6 +137,9 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
new String[]{"text/plain"},
new ClipData.Item(str));
+ if (LOG_CLIBOARD_ACCESS) {
+ Slog.i(TAG, "Setting the guest clipboard to '" + str + "'");
+ }
setAndroidClipboard.accept(clip);
} catch (ErrnoException | InterruptedIOException e) {
closePipe();
@@ -156,13 +164,22 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
}
private void setHostClipboardImpl(final String value) {
- try {
- if (isPipeOpened()) {
- sendMessage(value.getBytes());
- }
- } catch (ErrnoException | InterruptedIOException e) {
- Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
- } catch (IllegalArgumentException e) {
+ final FileDescriptor pipeFD = getPipeFD();
+
+ if (pipeFD != null) {
+ Thread t = new Thread(() -> {
+ if (LOG_CLIBOARD_ACCESS) {
+ Slog.i(TAG, "Setting the host clipboard to '" + value + "'");
+ }
+
+ try {
+ sendMessage(pipeFD, value.getBytes());
+ } catch (ErrnoException | InterruptedIOException e) {
+ Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
+ } catch (IllegalArgumentException e) {
+ }
+ });
+ t.start();
}
}
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 682f0dfe067c..c0df095c3289 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1320,6 +1320,7 @@ public class Vpn {
.setLegacyTypeName("VPN")
.setBypassableVpn(mConfig.allowBypass && !mLockdown)
.setVpnRequiresValidation(mConfig.requiresInternetValidation)
+ .setLocalRoutesExcludedForVpn(mConfig.excludeLocalRoutes)
.build();
capsBuilder.setOwnerUid(mOwnerUID);
@@ -3386,6 +3387,7 @@ public class Vpn {
mConfig.startTime = SystemClock.elapsedRealtime();
mConfig.proxyInfo = profile.proxy;
mConfig.requiresInternetValidation = profile.requiresInternetValidation;
+ mConfig.excludeLocalRoutes = profile.excludeLocalRoutes;
switch (profile.type) {
case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS:
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5d1ad2a377dd..e21edc9c4468 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -3939,12 +3939,22 @@ public final class DisplayManagerService extends SystemService {
* Listens to changes in device state and reports the state to LogicalDisplayMapper.
*/
class DeviceStateListener implements DeviceStateManager.DeviceStateCallback {
+ // Base state corresponds to the physical state of the device
+ private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE;
+
@Override
public void onStateChanged(int deviceState) {
+ boolean isDeviceStateOverrideActive = deviceState != mBaseState;
synchronized (mSyncRoot) {
- mLogicalDisplayMapper.setDeviceStateLocked(deviceState);
+ mLogicalDisplayMapper
+ .setDeviceStateLocked(deviceState, isDeviceStateOverrideActive);
}
}
+
+ @Override
+ public void onBaseStateChanged(int state) {
+ mBaseState = state;
+ }
};
private class BrightnessPair {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 7a0cf4b592e7..540ae8165dbd 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -73,6 +73,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final SurfaceControlProxy mSurfaceControlProxy;
+ private final boolean mIsBootDisplayModeSupported;
+
// Called with SyncRoot lock held.
public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener) {
@@ -85,6 +87,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
super(syncRoot, context, handler, listener, TAG);
mInjector = injector;
mSurfaceControlProxy = mInjector.getSurfaceControlProxy();
+ mIsBootDisplayModeSupported = mSurfaceControlProxy.getBootDisplayModeSupport();
}
@Override
@@ -349,8 +352,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
if (preferredRecord != null) {
int preferredModeId = preferredRecord.mMode.getModeId();
- if (mSurfaceControlProxy.getBootDisplayModeSupport()
- && mSystemPreferredModeId != preferredModeId) {
+ if (mIsBootDisplayModeSupported && mSystemPreferredModeId != preferredModeId) {
mSystemPreferredModeId = preferredModeId;
preferredModeChanged = true;
}
@@ -900,7 +902,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
updateDeviceInfoLocked();
- if (!mSurfaceControlProxy.getBootDisplayModeSupport()) {
+ if (!mIsBootDisplayModeSupported) {
return;
}
if (mUserPreferredModeId == INVALID_MODE_ID) {
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 6f5729f89e0f..add0a9f77108 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -359,7 +359,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mDeviceStateToLayoutMap.dumpLocked(ipw);
}
- void setDeviceStateLocked(int state) {
+ void setDeviceStateLocked(int state, boolean isOverrideActive) {
Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
+ ", interactive=" + mInteractive);
// As part of a state transition, we may need to turn off some displays temporarily so that
@@ -370,12 +370,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
resetLayoutLocked(mDeviceState, state, LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION);
}
mPendingDeviceState = state;
- final boolean wakeDevice = mDeviceStatesOnWhichToWakeUp.get(mPendingDeviceState)
- && !mDeviceStatesOnWhichToWakeUp.get(mDeviceState)
- && !mInteractive && mBootCompleted;
- final boolean sleepDevice = mDeviceStatesOnWhichToSleep.get(mPendingDeviceState)
- && !mDeviceStatesOnWhichToSleep.get(mDeviceState)
- && mInteractive && mBootCompleted;
+ final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
+ mInteractive, mBootCompleted);
+ final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
+ isOverrideActive, mInteractive, mBootCompleted);
// If all displays are off already, we can just transition here, unless we are trying to
// wake or sleep the device as part of this transition. In that case defer the final
@@ -429,6 +427,53 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
}
+ /**
+ * Returns if the device should be woken up or not. Called to check if the device state we are
+ * moving to is one that should awake the device, as well as if we are moving from a device
+ * state that shouldn't have been already woken from.
+ *
+ * @param pendingState device state we are moving to
+ * @param currentState device state we are currently in
+ * @param isInteractive if the device is in an interactive state
+ * @param isBootCompleted is the device fully booted
+ *
+ * @see #shouldDeviceBePutToSleep
+ * @see #setDeviceStateLocked
+ */
+ @VisibleForTesting
+ boolean shouldDeviceBeWoken(int pendingState, int currentState, boolean isInteractive,
+ boolean isBootCompleted) {
+ return mDeviceStatesOnWhichToWakeUp.get(pendingState)
+ && !mDeviceStatesOnWhichToWakeUp.get(currentState)
+ && !isInteractive && isBootCompleted;
+ }
+
+ /**
+ * Returns if the device should be put to sleep or not.
+ *
+ * Includes a check to verify that the device state that we are moving to, {@code pendingState},
+ * is the same as the physical state of the device, {@code baseState}. Different values for
+ * these parameters indicate a device state override is active, and we shouldn't put the device
+ * to sleep to provide a better user experience.
+ *
+ * @param pendingState device state we are moving to
+ * @param currentState device state we are currently in
+ * @param isOverrideActive if a device state override is currently active or not
+ * @param isInteractive if the device is in an interactive state
+ * @param isBootCompleted is the device fully booted
+ *
+ * @see #shouldDeviceBeWoken
+ * @see #setDeviceStateLocked
+ */
+ @VisibleForTesting
+ boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isOverrideActive,
+ boolean isInteractive, boolean isBootCompleted) {
+ return mDeviceStatesOnWhichToSleep.get(pendingState)
+ && !mDeviceStatesOnWhichToSleep.get(currentState)
+ && !isOverrideActive
+ && isInteractive && isBootCompleted;
+ }
+
private boolean areAllTransitioningDisplaysOffLocked() {
final int count = mLogicalDisplays.size();
for (int i = 0; i < count; i++) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index c0950bf13a1c..d249d578cf67 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -654,14 +654,17 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
protected int handleTextViewOn(HdmiCecMessage message) {
assertRunOnServiceThread();
- // Note that <Text View On> (and <Image View On>) command won't be handled here in
- // most cases. A dedicated microcontroller should be in charge while Android system
- // is in sleep mode, and the command need not be passed up to this service.
- // The only situation where the command reaches this handler is that sleep mode is
- // implemented in such a way that Android system is not really put to standby mode
- // but only the display is set to blank. Then the command leads to the effect of
+ // Note that if the device is in sleep mode, the <Text View On> (and <Image View On>)
+ // command won't be handled here in most cases. A dedicated microcontroller should be in
+ // charge while the Android system is in sleep mode, and the command doesn't need to be
+ // passed up to this service.
+ // The only situations where the command reaches this handler are
+ // 1. if sleep mode is implemented in such a way that Android system is not really put to
+ // standby mode but only the display is set to blank. Then the command leads to
// turning on the display by the invocation of PowerManager.wakeUp().
- if (mService.isPowerStandbyOrTransient() && getAutoWakeup()) {
+ // 2. if the device is in dream mode, not sleep mode. Then this command leads to
+ // waking up the device from dream mode by the invocation of PowerManager.wakeUp().
+ if (getAutoWakeup()) {
mService.wakeUp();
}
return Constants.HANDLED;
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 29e5f922b468..34e3ce1ab641 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -604,10 +604,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
List<S> services = mServicesCacheList.get(resolvedUserId);
if (services == null || services.size() == 0) {
final boolean disabled = isDisabledLocked(userId);
- if (mServiceNameResolver == null) {
- return null;
- }
- if (mServiceNameResolver.isConfiguredInMultipleMode()) {
+ if (mServiceNameResolver != null && mServiceNameResolver.isConfiguredInMultipleMode()) {
services = newServiceListLocked(resolvedUserId, disabled,
mServiceNameResolver.getServiceNameList(userId));
} else {
diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index 58413c9c5705..b8f1db402a55 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -152,7 +152,8 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
updateIsSetupComplete(mUserId);
mDisabled = disabled;
- if (mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
+ if (mMaster.mServiceNameResolver != null
+ && mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
updateServiceInfoListLocked();
} else {
updateServiceInfoLocked();
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index dbd3f3529208..d238dae634ad 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -19,6 +19,7 @@ package com.android.server.input;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import android.os.IBinder;
+import android.os.InputConfig;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputMonitor;
@@ -56,18 +57,13 @@ class GestureMonitorSpyWindow {
mWindowHandle.name = name;
mWindowHandle.token = mClientChannel.getToken();
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
- mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mWindowHandle.visible = true;
- mWindowHandle.focusable = false;
- mWindowHandle.hasWallpaper = false;
- mWindowHandle.paused = false;
mWindowHandle.ownerPid = pid;
mWindowHandle.ownerUid = uid;
- mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY;
mWindowHandle.scaleFactor = 1.0f;
- mWindowHandle.trustedOverlay = true;
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+ mWindowHandle.inputConfig =
+ InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setInputWindowInfo(mInputSurface, mWindowHandle);
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 3c454080ef1c..1a19385e71c5 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -19,6 +19,7 @@ package com.android.server.inputmethod;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import android.annotation.NonNull;
+import android.os.InputConfig;
import android.os.Process;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
@@ -56,20 +57,17 @@ final class HandwritingEventReceiverSurface {
mWindowHandle.name = name;
mWindowHandle.token = mClientChannel.getToken();
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
- mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mWindowHandle.visible = true;
- mWindowHandle.focusable = false;
- mWindowHandle.hasWallpaper = false;
- mWindowHandle.paused = false;
mWindowHandle.ownerPid = Process.myPid();
mWindowHandle.ownerUid = Process.myUid();
- mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
- | WindowManager.LayoutParams.INPUT_FEATURE_INTERCEPTS_STYLUS;
mWindowHandle.scaleFactor = 1.0f;
- mWindowHandle.trustedOverlay = true;
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+ mWindowHandle.inputConfig =
+ InputConfig.NOT_FOCUSABLE
+ | InputConfig.NOT_TOUCHABLE
+ | InputConfig.SPY
+ | InputConfig.INTERCEPTS_STYLUS
+ | InputConfig.TRUSTED_OVERLAY;
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setInputWindowInfo(mInputSurface, mWindowHandle);
@@ -85,7 +83,7 @@ final class HandwritingEventReceiverSurface {
void startIntercepting(int imePid, int imeUid) {
mWindowHandle.ownerPid = imePid;
mWindowHandle.ownerUid = imeUid;
- mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+ mWindowHandle.inputConfig &= ~InputConfig.SPY;
new SurfaceControl.Transaction()
.setInputWindowInfo(mInputSurface, mWindowHandle)
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
index 6cb3b3b6740d..e6fd40902386 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
@@ -32,6 +32,7 @@ import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
@@ -108,10 +109,10 @@ final class IInputMethodInvoker {
@AnyThread
void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
int configChanges, boolean stylusHwSupported,
- boolean shouldShowImeSwitcherWhenImeIsShown) {
+ @InputMethodNavButtonFlags int navButtonFlags) {
try {
mTarget.initializeInternal(token, privOps, configChanges, stylusHwSupported,
- shouldShowImeSwitcherWhenImeIsShown);
+ navButtonFlags);
} catch (RemoteException e) {
logRemoteException(e);
}
@@ -147,20 +148,19 @@ final class IInputMethodInvoker {
@AnyThread
void startInput(IBinder startInputToken, IInputContext inputContext, EditorInfo attribute,
- boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
+ boolean restarting, @InputMethodNavButtonFlags int navButtonFlags) {
try {
mTarget.startInput(startInputToken, inputContext, attribute, restarting,
- shouldShowImeSwitcherWhenImeIsShown);
+ navButtonFlags);
} catch (RemoteException e) {
logRemoteException(e);
}
}
@AnyThread
- void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown) {
+ void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
try {
- mTarget.onShouldShowImeSwitcherWhenImeIsShownChanged(
- shouldShowImeSwitcherWhenImeIsShown);
+ mTarget.onNavButtonFlagsChanged(navButtonFlags);
} catch (RemoteException e) {
logRemoteException(e);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index efe99d7611f9..1f9d08063714 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -121,6 +121,7 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.proto.ProtoOutputStream;
import android.view.IWindowManager;
import android.view.InputChannel;
@@ -155,6 +156,7 @@ import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.ImeTracing;
import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.InputMethodDebug;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
@@ -274,6 +276,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final InputMethodSettings mSettings;
final SettingsObserver mSettingsObserver;
final IWindowManager mIWindowManager;
+ private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid =
+ new SparseBooleanArray(0);
final WindowManagerInternal mWindowManagerInternal;
final PackageManagerInternal mPackageManagerInternal;
final InputManagerInternal mInputManagerInternal;
@@ -332,6 +336,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
private final HandwritingModeController mHwController;
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ private OverlayableSystemBooleanResourceWrapper mImeDrawsImeNavBarRes;
+
static class SessionState {
final ClientState client;
final IInputMethodInvoker method;
@@ -1378,6 +1386,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
clearPackageChangeState();
}
+ @Override
+ public void onUidRemoved(int uid) {
+ synchronized (ImfLock.class) {
+ mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid);
+ }
+ }
+
private void clearPackageChangeState() {
// No need to lock them because we access these fields only on getRegisteredHandler().
mChangedPackages.clear();
@@ -1713,11 +1728,43 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@GuardedBy("ImfLock.class")
+ private void recreateImeDrawsImeNavBarResIfNecessary(@UserIdInt int targetUserId) {
+ // Currently, com.android.internal.R.bool.config_imeDrawsImeNavBar is overlaid only for the
+ // profile parent user.
+ // TODO(b/221443458): See if we can make OverlayManager be aware of profile groups.
+ final int profileParentUserId = mUserManagerInternal.getProfileParentId(targetUserId);
+ if (mImeDrawsImeNavBarRes != null
+ && mImeDrawsImeNavBarRes.getUserId() != profileParentUserId) {
+ mImeDrawsImeNavBarRes.close();
+ mImeDrawsImeNavBarRes = null;
+ }
+ if (mImeDrawsImeNavBarRes == null) {
+ final Context userContext;
+ if (mContext.getUserId() == profileParentUserId) {
+ userContext = mContext;
+ } else {
+ userContext = mContext.createContextAsUser(UserHandle.of(profileParentUserId),
+ 0 /* flags */);
+ }
+ mImeDrawsImeNavBarRes = OverlayableSystemBooleanResourceWrapper.create(userContext,
+ com.android.internal.R.bool.config_imeDrawsImeNavBar, mHandler, resource -> {
+ synchronized (ImfLock.class) {
+ if (resource == mImeDrawsImeNavBarRes) {
+ sendOnNavButtonFlagsChangedLocked();
+ }
+ }
+ });
+ }
+ }
+
+ @GuardedBy("ImfLock.class")
private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
IInputMethodClient clientToBeReset) {
if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
+ " currentUserId=" + mSettings.getCurrentUserId());
+ recreateImeDrawsImeNavBarResIfNecessary(newUserId);
+
// ContentObserver should be registered again when the user is changed
mSettingsObserver.registerContentObserverLocked(newUserId);
@@ -1822,6 +1869,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
});
}
+ recreateImeDrawsImeNavBarResIfNecessary(currentUserId);
+
mMyPackageMonitor.register(mContext, null, UserHandle.ALL, true);
mSettingsObserver.registerContentObserverLocked(currentUserId);
@@ -2402,12 +2451,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
true /* direct */);
}
- final boolean shouldShowImeSwitcherWhenImeIsShown =
- shouldShowImeSwitcherWhenImeIsShownLocked();
+ @InputMethodNavButtonFlags
+ final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
final SessionState session = mCurClient.curSession;
setEnabledSessionLocked(session);
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting,
- shouldShowImeSwitcherWhenImeIsShown);
+ navButtonFlags);
if (mShowRequested) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlagsLocked(), null,
@@ -2671,7 +2720,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
+ mCurTokenDisplayId);
}
inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
- configChanges, supportStylusHw, shouldShowImeSwitcherWhenImeIsShownLocked());
+ configChanges, supportStylusHw, getInputMethodNavButtonFlagsLocked());
}
@AnyThread
@@ -2928,9 +2977,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@GuardedBy("ImfLock.class")
- boolean shouldShowImeSwitcherWhenImeIsShownLocked() {
- return shouldShowImeSwitcherLocked(
+ @InputMethodNavButtonFlags
+ private int getInputMethodNavButtonFlagsLocked() {
+ final boolean canImeDrawsImeNavBar =
+ mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get();
+ final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE);
+ return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
+ | (shouldShowImeSwitcherWhenImeIsShown
+ ? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
}
@GuardedBy("ImfLock.class")
@@ -3193,7 +3248,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
- sendShouldShowImeSwitcherWhenImeIsShownLocked();
+ sendOnNavButtonFlagsChangedLocked();
}
@GuardedBy("ImfLock.class")
@@ -4150,13 +4205,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
* @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)}
*/
@Override
- public int getInputMethodWindowVisibleHeight() {
- // TODO(yukawa): Should we verify the display ID?
- final int curTokenDisplayId;
- synchronized (ImfLock.class) {
- curTokenDisplayId = mCurTokenDisplayId;
- }
- return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
+ @Deprecated
+ public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
+ int callingUid = Binder.getCallingUid();
+ return Binder.withCleanCallingIdentity(() -> {
+ final int curTokenDisplayId;
+ synchronized (ImfLock.class) {
+ if (!canInteractWithImeLocked(callingUid, client,
+ "getInputMethodWindowVisibleHeight")) {
+ if (!mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.get(callingUid)) {
+ EventLog.writeEvent(0x534e4554, "204906124", callingUid, "");
+ mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.put(callingUid, true);
+ }
+ return 0;
+ }
+ // This should probably use the caller's display id, but because this is unsupported
+ // and maintained only for compatibility, there's no point in fixing it.
+ curTokenDisplayId = mCurTokenDisplayId;
+ }
+ return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
+ });
}
@Override
@@ -4657,7 +4725,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mMenuController.handleHardKeyboardStatusChange(msg.arg1 == 1);
synchronized (ImfLock.class) {
- sendShouldShowImeSwitcherWhenImeIsShownLocked();
+ sendOnNavButtonFlagsChangedLocked();
}
return true;
case MSG_SYSTEM_UNLOCK_USER: {
@@ -4927,7 +4995,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
- sendShouldShowImeSwitcherWhenImeIsShownLocked();
+ sendOnNavButtonFlagsChangedLocked();
// Notify InputMethodListListeners of the new installed InputMethods.
final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
@@ -4936,14 +5004,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@GuardedBy("ImfLock.class")
- void sendShouldShowImeSwitcherWhenImeIsShownLocked() {
+ void sendOnNavButtonFlagsChangedLocked() {
final IInputMethodInvoker curMethod = mBindingController.getCurMethod();
if (curMethod == null) {
// No need to send the data if the IME is not yet bound.
return;
}
- curMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
- shouldShowImeSwitcherWhenImeIsShownLocked());
+ curMethod.onNavButtonFlagsChanged(getInputMethodNavButtonFlagsLocked());
}
@GuardedBy("ImfLock.class")
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 98bde11ad517..c255fe14c03e 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -203,7 +203,7 @@ final class InputMethodMenuController {
attrs.setTitle("Select input method");
w.setAttributes(attrs);
mService.updateSystemUiLocked();
- mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
+ mService.sendOnNavButtonFlagsChangedLocked();
mSwitchingDialog.show();
}
}
@@ -239,7 +239,7 @@ final class InputMethodMenuController {
mSwitchingDialogTitleView = null;
mService.updateSystemUiLocked();
- mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
+ mService.sendOnNavButtonFlagsChangedLocked();
mDialogBuilder = null;
mIms = null;
}
diff --git a/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java b/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java
new file mode 100644
index 000000000000..33e7a7621340
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java
@@ -0,0 +1,159 @@
+/*
+ * 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.inputmethod;
+
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
+
+import android.annotation.AnyThread;
+import android.annotation.BoolRes;
+import android.annotation.NonNull;
+import android.annotation.UserHandleAware;
+import android.annotation.UserIdInt;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.PatternMatcher;
+import android.util.Slog;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+/**
+ * A wrapper object for any boolean resource defined in {@code "android"} package, in a way that is
+ * aware of per-user Runtime Resource Overlay (RRO).
+ */
+final class OverlayableSystemBooleanResourceWrapper implements AutoCloseable {
+ private static final String TAG = "OverlayableSystemBooleanResourceWrapper";
+
+ private static final String SYSTEM_PACKAGE_NAME = "android";
+
+ @UserIdInt
+ private final int mUserId;
+ @NonNull
+ private final AtomicBoolean mValueRef;
+ @NonNull
+ private final AtomicReference<Runnable> mCleanerRef;
+
+ /**
+ * Creates {@link OverlayableSystemBooleanResourceWrapper} for the given boolean resource ID
+ * with a value change callback for the user associated with the {@link Context}.
+ *
+ * @param userContext The {@link Context} to be used to access the resource. This needs to be
+ * associated with the right user because the Runtime Resource Overlay (RRO)
+ * is per-user configuration.
+ * @param boolResId The resource ID to be queried.
+ * @param handler {@link Handler} to be used to dispatch {@code callback}.
+ * @param callback The callback to be notified when the specified value might be updated.
+ * The callback needs to take care of spurious wakeup. The value returned from
+ * {@link #get()} may look to be exactly the same as the previously read value
+ * e.g. when the value is changed from {@code false} to {@code true} to
+ * {@code false} in a very short period of time, because {@link #get()} always
+ * does volatile-read.
+ * @return New {@link OverlayableSystemBooleanResourceWrapper}.
+ */
+ @NonNull
+ @UserHandleAware
+ static OverlayableSystemBooleanResourceWrapper create(@NonNull Context userContext,
+ @BoolRes int boolResId, @NonNull Handler handler,
+ @NonNull Consumer<OverlayableSystemBooleanResourceWrapper> callback) {
+
+ // Note that we cannot fully trust this initial value due to the dead time between obtaining
+ // the value here and setting up a broadcast receiver for change callback below.
+ // We will refresh the value again later after setting up the change callback anyway.
+ final AtomicBoolean valueRef = new AtomicBoolean(evaluate(userContext, boolResId));
+
+ final AtomicReference<Runnable> cleanerRef = new AtomicReference<>();
+
+ final OverlayableSystemBooleanResourceWrapper object =
+ new OverlayableSystemBooleanResourceWrapper(userContext.getUserId(), valueRef,
+ cleanerRef);
+
+ final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+ intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
+ intentFilter.addDataSchemeSpecificPart(SYSTEM_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
+
+ final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final boolean newValue = evaluate(userContext, boolResId);
+ if (newValue != valueRef.getAndSet(newValue)) {
+ callback.accept(object);
+ }
+ }
+ };
+ userContext.registerReceiver(broadcastReceiver, intentFilter,
+ null /* broadcastPermission */, handler,
+ Context.RECEIVER_NOT_EXPORTED);
+ cleanerRef.set(() -> userContext.unregisterReceiver(broadcastReceiver));
+
+ // Make sure that the initial observable value is obtained after the change callback is set.
+ valueRef.set(evaluate(userContext, boolResId));
+ return object;
+ }
+
+ private OverlayableSystemBooleanResourceWrapper(@UserIdInt int userId,
+ @NonNull AtomicBoolean valueRef, @NonNull AtomicReference<Runnable> cleanerRef) {
+ mUserId = userId;
+ mValueRef = valueRef;
+ mCleanerRef = cleanerRef;
+ }
+
+ /**
+ * @return The boolean resource value.
+ */
+ @AnyThread
+ boolean get() {
+ return mValueRef.get();
+ }
+
+ /**
+ * @return The user ID associated with this resource reader.
+ */
+ @AnyThread
+ @UserIdInt
+ int getUserId() {
+ return mUserId;
+ }
+
+ @AnyThread
+ private static boolean evaluate(@NonNull Context context, @BoolRes int boolResId) {
+ try {
+ return context.getPackageManager()
+ .getResourcesForApplication(SYSTEM_PACKAGE_NAME)
+ .getBoolean(boolResId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "getResourcesForApplication(\"" + SYSTEM_PACKAGE_NAME + "\") failed", e);
+ return false;
+ }
+ }
+
+ /**
+ * Cleans up the callback.
+ */
+ @AnyThread
+ @Override
+ public void close() {
+ final Runnable cleaner = mCleanerRef.getAndSet(null);
+ if (cleaner != null) {
+ cleaner.run();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 48ad22cb12ff..9f573c2ec7a8 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1011,10 +1011,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(ACTION_PACKAGE_ADDED);
packageFilter.addDataScheme("package");
- mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
+ mContext.registerReceiverForAllUsers(mPackageReceiver, packageFilter, null, mHandler);
// listen for UID changes to update policy
- mContext.registerReceiver(
+ mContext.registerReceiverForAllUsers(
mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
// listen for user changes to update policy
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c4731aa7b522..d65dc13b72e3 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3746,6 +3746,10 @@ public class NotificationManagerService extends SystemService {
if (!hadChannel && hasChannel && !hasRequestedNotificationPermission
&& startingTaskId != ActivityTaskManager.INVALID_TASK_ID) {
hasRequestedNotificationPermission = true;
+ if (mPermissionPolicyInternal == null) {
+ mPermissionPolicyInternal =
+ LocalServices.getService(PermissionPolicyInternal.class);
+ }
mHandler.post(new ShowNotificationPermissionPromptRunnable(pkg,
UserHandle.getUserId(uid), startingTaskId,
mPermissionPolicyInternal));
@@ -3764,19 +3768,7 @@ public class NotificationManagerService extends SystemService {
try {
int uid = mPackageManager.getPackageUid(pkg, 0,
UserHandle.getUserId(Binder.getCallingUid()));
- List<ActivityManager.AppTask> tasks = mAtm.getAppTasks(pkg, uid);
- for (int i = 0; i < tasks.size(); i++) {
- ActivityManager.RecentTaskInfo task = tasks.get(i).getTaskInfo();
- if (mPermissionPolicyInternal == null) {
- mPermissionPolicyInternal =
- LocalServices.getService(PermissionPolicyInternal.class);
- }
- if (mPermissionPolicyInternal != null
- && mPermissionPolicyInternal.canShowPermissionPromptForTask(task)) {
- taskId = task.taskId;
- break;
- }
- }
+ taskId = mAtm.getTaskToShowPermissionDialogOn(pkg, uid);
} catch (RemoteException e) {
// Do nothing
}
@@ -4068,13 +4060,12 @@ public class NotificationManagerService extends SystemService {
@Override
public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(
- String pkg, int userId) {
+ String pkg, int uid) {
checkCallerIsSystem();
- if (!areNotificationsEnabledForPackage(pkg,
- mPackageManagerInternal.getPackageUid(pkg, 0, userId))) {
+ if (!areNotificationsEnabledForPackage(pkg, uid)) {
return ParceledListSlice.emptyList();
}
- return mPreferencesHelper.getNotificationChannelsBypassingDnd(pkg, userId);
+ return mPreferencesHelper.getNotificationChannelsBypassingDnd(pkg, uid);
}
@Override
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 6b9e374771ff..e551f1056b24 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -35,6 +35,7 @@ import android.util.ArrayMap;
import android.util.Pair;
import android.util.Slog;
+import com.android.internal.util.ArrayUtils;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.util.Collections;
@@ -178,13 +179,16 @@ public final class PermissionHelper {
boolean userSet, boolean reviewRequired) {
assertFlag();
final long callingId = Binder.clearCallingIdentity();
- // Do not change fixed permissions, and do not change non-user set permissions that are
- // granted by default, or granted by role.
- if (isPermissionFixed(packageName, userId)
- || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
- return;
- }
try {
+ // Do not change the permission if the package doesn't request it, do not change fixed
+ // permissions, and do not change non-user set permissions that are granted by default,
+ // or granted by role.
+ if (!packageRequestsNotificationPermission(packageName, userId)
+ || isPermissionFixed(packageName, userId)
+ || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
+ return;
+ }
+
boolean currentlyGranted = mPmi.checkPermission(packageName, NOTIFICATION_PERMISSION,
userId) != PackageManager.PERMISSION_DENIED;
if (grant && !reviewRequired && !currentlyGranted) {
@@ -278,6 +282,19 @@ public final class PermissionHelper {
}
}
+ private boolean packageRequestsNotificationPermission(String packageName,
+ @UserIdInt int userId) {
+ assertFlag();
+ try {
+ String[] permissions = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS,
+ userId).requestedPermissions;
+ return ArrayUtils.contains(permissions, NOTIFICATION_PERMISSION);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Could not reach system server", e);
+ }
+ return false;
+ }
+
private void assertFlag() {
if (!mMigrationEnabled) {
throw new IllegalStateException("Method called without checking flag value");
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 11858904a69a..1f7d65e6c604 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1669,14 +1669,14 @@ public class PreferencesHelper implements RankingConfig {
}
/**
- * Gets all notification channels associated with the given pkg and userId that can bypass dnd
+ * Gets all notification channels associated with the given pkg and uid that can bypass dnd
*/
public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(String pkg,
- int userId) {
+ int uid) {
List<NotificationChannel> channels = new ArrayList<>();
synchronized (mPackagePreferences) {
final PackagePreferences r = mPackagePreferences.get(
- packagePreferencesKey(pkg, userId));
+ packagePreferencesKey(pkg, uid));
if (r != null) {
for (NotificationChannel channel : r.channels.values()) {
if (channelIsLiveLocked(r, channel) && channel.canBypassDnd()) {
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index 2a6dd8410acb..b0d40efed690 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -112,7 +112,7 @@ public class ZenModeFiltering {
}
if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
if (consolidatedPolicy.allowRepeatCallers()
- && REPEAT_CALLERS.isRepeat(context, extras)) {
+ && REPEAT_CALLERS.isRepeat(context, extras, null)) {
ZenLog.traceMatchesCallFilter(true, "repeat caller");
return true;
}
@@ -229,7 +229,8 @@ public class ZenModeFiltering {
}
if (isCall(record)) {
if (policy.allowRepeatCallers()
- && REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
+ && REPEAT_CALLERS.isRepeat(
+ mContext, extras(record), record.getPhoneNumbers())) {
ZenLog.traceNotIntercepted(record, "repeatCaller");
return false;
}
@@ -350,6 +351,9 @@ public class ZenModeFiltering {
private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
private int mThresholdMinutes;
+ // Record all people URIs in the extras bundle as well as the provided phoneNumbers set
+ // as callers. The phoneNumbers set is used to pass in any additional phone numbers
+ // associated with the people URIs as separately retrieved from contacts.
private synchronized void recordCall(Context context, Bundle extras,
ArraySet<String> phoneNumbers) {
setThresholdMinutes(context);
@@ -362,7 +366,13 @@ public class ZenModeFiltering {
recordCallers(extraPeople, phoneNumbers, now);
}
- private synchronized boolean isRepeat(Context context, Bundle extras) {
+ // Determine whether any people in the provided extras bundle or phone number set is
+ // a repeat caller. The extras bundle contains the people associated with a specific
+ // notification, and will suffice for most callers; the phoneNumbers array may be used
+ // to additionally check any specific phone numbers previously retrieved from contacts
+ // associated with the people in the extras bundle.
+ private synchronized boolean isRepeat(Context context, Bundle extras,
+ ArraySet<String> phoneNumbers) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return false;
final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
@@ -370,7 +380,7 @@ public class ZenModeFiltering {
final long now = System.currentTimeMillis();
cleanUp(mTelCalls, now);
cleanUp(mOtherCalls, now);
- return checkCallers(context, extraPeople);
+ return checkCallers(context, extraPeople, phoneNumbers);
}
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
@@ -433,7 +443,31 @@ public class ZenModeFiltering {
}
}
- private synchronized boolean checkCallers(Context context, String[] people) {
+ // helper function to check mTelCalls array for a number, and also check its decoded
+ // version
+ private synchronized boolean checkForNumber(String number, String defaultCountryCode) {
+ if (mTelCalls.containsKey(number)) {
+ // check directly via map first
+ return true;
+ } else {
+ // see if a number that matches via areSameNumber exists
+ String numberToCheck = Uri.decode(number);
+ if (numberToCheck != null) {
+ for (String prev : mTelCalls.keySet()) {
+ if (PhoneNumberUtils.areSamePhoneNumber(
+ numberToCheck, prev, defaultCountryCode)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ // Check whether anyone in the provided array of people URIs or phone number set matches a
+ // previously recorded phone call.
+ private synchronized boolean checkCallers(Context context, String[] people,
+ ArraySet<String> phoneNumbers) {
// get the default country code for checking telephone numbers
final String defaultCountryCode =
context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
@@ -443,20 +477,8 @@ public class ZenModeFiltering {
final Uri uri = Uri.parse(person);
if ("tel".equals(uri.getScheme())) {
String number = uri.getSchemeSpecificPart();
- if (mTelCalls.containsKey(number)) {
- // check directly via map first
+ if (checkForNumber(number, defaultCountryCode)) {
return true;
- } else {
- // see if a number that matches via areSameNumber exists
- String numberToCheck = Uri.decode(number);
- if (numberToCheck != null) {
- for (String prev : mTelCalls.keySet()) {
- if (PhoneNumberUtils.areSamePhoneNumber(
- numberToCheck, prev, defaultCountryCode)) {
- return true;
- }
- }
- }
}
} else {
if (mOtherCalls.containsKey(person)) {
@@ -464,6 +486,17 @@ public class ZenModeFiltering {
}
}
}
+
+ // also check any passed-in phone numbers
+ if (phoneNumbers != null) {
+ for (String num : phoneNumbers) {
+ if (checkForNumber(num, defaultCountryCode)) {
+ return true;
+ }
+ }
+ }
+
+ // no matches
return false;
}
}
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 0b0d1458c8de..c24bfec5fb43 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -218,8 +218,9 @@ final class AppDataHelper {
final String seInfo = pkgSeInfo + seInfoUser;
final int targetSdkVersion = pkg.getTargetSdkVersion();
+ final boolean usesSdk = !pkg.getUsesSdkLibraries().isEmpty();
final CreateAppDataArgs args = Installer.buildCreateAppDataArgs(volumeUuid, packageName,
- userId, flags, appId, seInfo, targetSdkVersion);
+ userId, flags, appId, seInfo, targetSdkVersion, usesSdk);
args.previousAppId = previousAppId;
return batch.createAppData(args).whenComplete((ceDataInode, e) -> {
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 31df0a53eaa9..ecbb4a9d45a1 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -557,7 +557,7 @@ public final class BackgroundDexOptService {
/** Gets the size of a package. */
private long getPackageSize(PackageManagerService pm, String pkg) {
- PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
+ PackageInfo info = pm.snapshotComputer().getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
long size = 0;
if (info != null && info.applicationInfo != null) {
File path = Paths.get(info.applicationInfo.sourceDir).toFile();
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 2a4882ac7d4f..6103d688e2b1 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -284,6 +284,21 @@ public interface Computer extends PackageDataSnapshot {
@Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
+
+ /**
+ * Checks if the request is from the system or an app that has the appropriate cross-user
+ * permissions defined as follows:
+ * <ul>
+ * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
+ * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
+ * to the caller.</li>
+ * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
+ * group as the caller.</li>
+ * </ul>
+ *
+ * @param checkShell whether to prevent shell from access if there's a debugging restriction
+ * @param message the message to log on security exception
+ */
@Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message);
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 58f9bb2c1902..a9dc0f3854f0 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -66,6 +66,8 @@ import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.wm.ActivityTaskManagerInternal;
+import dalvik.system.VMRuntime;
+
import java.util.Collections;
import java.util.List;
@@ -245,8 +247,11 @@ final class DeletePackageHelper {
info.sendSystemPackageUpdatedBroadcasts(disabledSystemPs.getAppId());
}
}
- // Force a gc here.
- Runtime.getRuntime().gc();
+
+ // Force a gc to clear up things.
+ // Ask for a background one, it's fine to go on and not block here.
+ VMRuntime.getRuntime().requestConcurrentGC();
+
// Delete the resources here after sending the broadcast to let
// other processes clean up before deleting resources.
synchronized (mPm.mInstallLock) {
@@ -508,6 +513,7 @@ final class DeletePackageHelper {
outInfo.mRemovedAppId = ps.getAppId();
outInfo.mRemovedUsers = userIds;
outInfo.mBroadcastUsers = userIds;
+ outInfo.mIsExternal = ps.isExternalStorage();
}
}
@@ -679,7 +685,8 @@ final class DeletePackageHelper {
return;
}
- if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) {
+ if (!deleteAllUsers && mPm.mIPackageManager
+ .getBlockUninstallForUser(internalPackageName, userId)) {
mPm.mHandler.post(() -> {
try {
observer.onPackageDeleted(packageName,
@@ -699,11 +706,14 @@ final class DeletePackageHelper {
// Queue up an async operation since the package deletion may take a little while.
mPm.mHandler.post(() -> {
int returnCode;
- final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPackageName);
+ final Computer innerSnapshot = mPm.snapshotComputer();
+ final PackageStateInternal packageState =
+ innerSnapshot.getPackageStateInternal(internalPackageName);
boolean doDeletePackage = true;
- if (ps != null) {
+ if (packageState != null) {
final boolean targetIsInstantApp =
- ps.getInstantApp(UserHandle.getUserId(callingUid));
+ packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid))
+ .isInstantApp();
doDeletePackage = !targetIsInstantApp
|| canViewInstantApps;
}
@@ -712,7 +722,7 @@ final class DeletePackageHelper {
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags, false /*removedBySystem*/);
} else {
- int[] blockUninstallUserIds = getBlockUninstallForUsers(
+ int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot,
internalPackageName, users);
// If nobody is blocking uninstall, proceed with delete for all users
if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
@@ -763,39 +773,40 @@ final class DeletePackageHelper {
}
final int callingUserId = UserHandle.getUserId(callingUid);
// If the caller installed the pkgName, then allow it to silently uninstall.
- if (callingUid == mPm.getPackageUid(
- mPm.getInstallerPackageName(pkgName), 0, callingUserId)) {
+ if (callingUid == mPm.mIPackageManager.getPackageUid(
+ mPm.mIPackageManager.getInstallerPackageName(pkgName), 0, callingUserId)) {
return true;
}
// Allow package verifier to silently uninstall.
- if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.getPackageUid(
- mPm.mRequiredVerifierPackage, 0, callingUserId)) {
+ if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.mIPackageManager
+ .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) {
return true;
}
// Allow package uninstaller to silently uninstall.
- if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.getPackageUid(
- mPm.mRequiredUninstallerPackage, 0, callingUserId)) {
+ if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.mIPackageManager
+ .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) {
return true;
}
// Allow storage manager to silently uninstall.
- if (mPm.mStorageManagerPackage != null && callingUid == mPm.getPackageUid(
+ if (mPm.mStorageManagerPackage != null && callingUid == mPm.mIPackageManager.getPackageUid(
mPm.mStorageManagerPackage, 0, callingUserId)) {
return true;
}
// Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
// uninstall for device owner provisioning.
- return mPm.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
+ return mPm.mIPackageManager.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
== PERMISSION_GRANTED;
}
- private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
+ private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName,
+ int[] userIds) {
int[] result = EMPTY_INT_ARRAY;
for (int userId : userIds) {
- if (mPm.getBlockUninstallForUser(packageName, userId)) {
+ if (snapshot.getBlockUninstallForUser(packageName, userId)) {
result = ArrayUtils.appendInt(result, userId);
}
}
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index c8326931f6fd..74ea7cc9b4e1 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -304,7 +304,8 @@ final class DexOptHelper {
/*package*/ boolean performDexOpt(DexoptOptions options) {
if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
return false;
- } else if (mPm.isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
+ } else if (mPm.mIPackageManager.isInstantApp(options.getPackageName(),
+ UserHandle.getCallingUserId())) {
return false;
}
diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java
index 2b46ed404945..05ef3c4ec300 100644
--- a/services/core/java/com/android/server/pm/DumpHelper.java
+++ b/services/core/java/com/android/server/pm/DumpHelper.java
@@ -288,6 +288,8 @@ final class DumpHelper {
ipw.decreaseIndent();
}
+ final Computer snapshot = mPm.snapshotComputer();
+
if (dumpState.isDumping(DumpState.DUMP_VERIFIERS)
&& packageName == null) {
final String requiredVerifierPackage = mPm.mRequiredVerifierPackage;
@@ -299,14 +301,14 @@ final class DumpHelper {
pw.print(" Required: ");
pw.print(requiredVerifierPackage);
pw.print(" (uid=");
- pw.print(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
- UserHandle.USER_SYSTEM));
+ pw.print(snapshot.getPackageUid(requiredVerifierPackage,
+ MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
pw.println(")");
} else if (requiredVerifierPackage != null) {
pw.print("vrfy,"); pw.print(requiredVerifierPackage);
pw.print(",");
- pw.println(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
- UserHandle.USER_SYSTEM));
+ pw.println(snapshot.getPackageUid(requiredVerifierPackage,
+ MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
}
}
@@ -324,14 +326,14 @@ final class DumpHelper {
pw.print(" Using: ");
pw.print(verifierPackageName);
pw.print(" (uid=");
- pw.print(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
- UserHandle.USER_SYSTEM));
+ pw.print(snapshot.getPackageUid(verifierPackageName,
+ MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
pw.println(")");
} else if (verifierPackageName != null) {
pw.print("dv,"); pw.print(verifierPackageName);
pw.print(",");
- pw.println(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
- UserHandle.USER_SYSTEM));
+ pw.println(snapshot.getPackageUid(verifierPackageName,
+ MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
}
} else {
pw.println();
@@ -405,7 +407,7 @@ final class DumpHelper {
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
- mPm.mComponentResolver.dumpContentProviders(mPm.snapshotComputer(), pw, dumpState,
+ mPm.mComponentResolver.dumpContentProviders(snapshot, pw, dumpState,
packageName);
}
@@ -661,13 +663,14 @@ final class DumpHelper {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
synchronized (mPm.mLock) {
+ final Computer snapshot = mPm.snapshotComputer();
final long requiredVerifierPackageToken =
proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
proto.write(PackageServiceDumpProto.PackageShortProto.NAME,
mPm.mRequiredVerifierPackage);
proto.write(
PackageServiceDumpProto.PackageShortProto.UID,
- mPm.getPackageUid(
+ snapshot.getPackageUid(
mPm.mRequiredVerifierPackage,
MATCH_DEBUG_TRIAGED_MISSING,
UserHandle.USER_SYSTEM));
@@ -682,7 +685,7 @@ final class DumpHelper {
proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
proto.write(
PackageServiceDumpProto.PackageShortProto.UID,
- mPm.getPackageUid(
+ snapshot.getPackageUid(
verifierPackageName,
MATCH_DEBUG_TRIAGED_MISSING,
UserHandle.USER_SYSTEM));
diff --git a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
index c65c2b112706..b4bcd5b3308c 100644
--- a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
+++ b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
@@ -22,11 +22,12 @@ import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManagerInternal;
import android.os.Process;
-import android.os.ServiceManager;
import android.util.EventLog;
import android.util.Log;
+import com.android.server.LocalServices;
import com.android.server.pm.dex.DynamicCodeLogger;
import libcore.util.HexEncoding;
@@ -133,8 +134,7 @@ public class DynamicCodeLoggingService extends JobService {
}
private static DynamicCodeLogger getDynamicCodeLogger() {
- PackageManagerService pm = (PackageManagerService) ServiceManager.getService("package");
- return pm.getDexManager().getDynamicCodeLogger();
+ return LocalServices.getService(PackageManagerInternal.class).getDynamicCodeLogger();
}
private class IdleLoggingThread extends Thread {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index ceab92577bb3..b5d63f3bb4c0 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -86,6 +86,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
+import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -287,6 +288,12 @@ final class InstallPackageHelper {
SharedUserSetting sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(pkgSetting);
if (sharedUserSetting != null) {
sharedUserSetting.addPackage(pkgSetting);
+ if (parsedPackage.isLeavingSharedUid()
+ && SharedUidMigration.applyStrategy(BEST_EFFORT)
+ && sharedUserSetting.isSingleUser()) {
+ // Attempt the transparent shared UID migration
+ mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
+ }
}
if (reconciledPkg.mInstallArgs != null
&& reconciledPkg.mInstallArgs.mForceQueryableOverride) {
@@ -1663,6 +1670,7 @@ final class InstallPackageHelper {
final int userId = uninstalledUsers[i];
res.mRemovedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId));
}
+ res.mRemovedInfo.mIsExternal = oldPackage.isExternalStorage();
sysPkg = oldPackage.isSystem();
if (sysPkg) {
@@ -1937,21 +1945,6 @@ final class InstallPackageHelper {
}
}
// Successfully deleted the old package; proceed with replace.
-
- // If deleted package lived in a container, give users a chance to
- // relinquish resources before killing.
- if (oldPackage.isExternalStorage()) {
- if (DEBUG_INSTALL) {
- Slog.i(TAG, "upgrading pkg " + oldPackage
- + " is ASEC-hosted -> UNAVAILABLE");
- }
- final int[] uidArray = new int[]{oldPackage.getUid()};
- final ArrayList<String> pkgList = new ArrayList<>(1);
- pkgList.add(oldPackage.getPackageName());
- mBroadcastHelper.sendResourcesChangedBroadcast(
- false, true, pkgList, uidArray, null);
- }
-
// Update the in-memory copy of the previous code paths.
PackageSetting ps1 = mPm.mSettings.getPackageLPr(
reconciledPkg.mPrepareResult.mExistingPackage.getPackageName());
@@ -2230,23 +2223,8 @@ final class InstallPackageHelper {
}
incrementalStorages.add(storage);
}
- int previousAppId = 0;
- if (reconciledPkg.mScanResult.needsNewAppId()) {
- // Only set previousAppId if the app is migrating out of shared UID
- previousAppId = reconciledPkg.mScanResult.mPreviousAppId;
-
- if (pkg.shouldInheritKeyStoreKeys()) {
- // Migrate keystore data
- mAppDataHelper.migrateKeyStoreData(
- previousAppId, reconciledPkg.mPkgSetting.getAppId());
- }
-
- if (reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId == previousAppId) {
- // If the previous app ID is removed, clear the keys
- mAppDataHelper.clearKeystoreData(UserHandle.USER_ALL, previousAppId);
- }
- }
- mAppDataHelper.prepareAppDataPostCommitLIF(pkg, previousAppId);
+ // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+ mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
if (reconciledPkg.mPrepareResult.mClearCodeCache) {
mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
@@ -2647,6 +2625,17 @@ final class InstallPackageHelper {
// Send the removed broadcasts
if (res.mRemovedInfo != null) {
+ if (res.mRemovedInfo.mIsExternal) {
+ if (DEBUG_INSTALL) {
+ Slog.i(TAG, "upgrading pkg " + res.mRemovedInfo.mRemovedPackage
+ + " is ASEC-hosted -> UNAVAILABLE");
+ }
+ final int[] uidArray = new int[]{res.mRemovedInfo.mUid};
+ final ArrayList<String> pkgList = new ArrayList<>(1);
+ pkgList.add(res.mRemovedInfo.mRemovedPackage);
+ mBroadcastHelper.sendResourcesChangedBroadcast(
+ false, true, pkgList, uidArray, null);
+ }
res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
}
@@ -2878,13 +2867,14 @@ final class InstallPackageHelper {
VMRuntime.getRuntime().requestConcurrentGC();
}
+ final Computer snapshot = mPm.snapshotComputer();
// Notify DexManager that the package was installed for new users.
// The updated users should already be indexed and the package code paths
// should not change.
// Don't notify the manager for ephemeral apps as they are not expected to
// survive long enough to benefit of background optimizations.
for (int userId : firstUserIds) {
- PackageInfo info = mPm.getPackageInfo(packageName, /*flags*/ 0, userId);
+ PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId);
// There's a race currently where some install events may interleave with an
// uninstall. This can lead to package info being null (b/36642664).
if (info != null) {
@@ -2991,7 +2981,6 @@ final class InstallPackageHelper {
* APK will be installed and the package will be disabled. To recover from this situation,
* the user will need to go into system settings and re-enable the package.
*/
- @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
boolean enableCompressedPackage(AndroidPackage stubPkg,
@NonNull PackageSetting stubPkgSetting) {
final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY
@@ -3001,8 +2990,8 @@ final class InstallPackageHelper {
try (PackageFreezer freezer =
mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
+ mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
synchronized (mPm.mLock) {
- mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
try {
mSharedLibraries.updateSharedLibrariesLPw(
pkg, stubPkgSetting, null, null,
@@ -3030,8 +3019,7 @@ final class InstallPackageHelper {
installPackageFromSystemLIF(stubPkg.getPath(),
mPm.mUserManager.getUserIds() /*allUserHandles*/,
null /*origUserHandles*/,
- true /*writeSettings*/,
- Process.INVALID_UID /*previousAppId*/);
+ true /*writeSettings*/);
} catch (PackageManagerException pme) {
// Serious WTF; we have to be able to install the stub
Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
@@ -3059,7 +3047,7 @@ final class InstallPackageHelper {
return true;
}
- @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+ @GuardedBy("mPm.mInstallLock")
private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
@ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags)
@@ -3152,27 +3140,26 @@ final class InstallPackageHelper {
mPm.mSettings.enableSystemPackageLPw(disabledPs.getPkg().getPackageName());
// Remove any native libraries from the upgraded package.
PackageManagerServiceUtils.removeNativeBinariesLI(deletedPs);
-
- // Install the system package
- if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
- try {
- synchronized (mPm.mInstallLock) {
- final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
- final int previousAppId = disabledPs.getAppId() != deletedPs.getAppId()
- ? deletedPs.getAppId() : Process.INVALID_UID;
- installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
- origUsers, writeSettings, previousAppId);
- }
- } catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
- + e.getMessage());
- // TODO(b/194319951): can we avoid this; throw would come from scan...
- throw new SystemDeleteException(e);
- } finally {
- if (disabledPs.getPkg().isStub()) {
- // We've re-installed the stub; make sure it's disabled here. If package was
- // originally enabled, we'll install the compressed version of the application
- // and re-enable it afterward.
+ }
+ // Install the system package
+ if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
+ try {
+ synchronized (mPm.mInstallLock) {
+ final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
+ installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
+ origUsers, writeSettings);
+ }
+ } catch (PackageManagerException e) {
+ Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
+ + e.getMessage());
+ // TODO(b/194319951): can we avoid this; throw would come from scan...
+ throw new SystemDeleteException(e);
+ } finally {
+ if (disabledPs.getPkg().isStub()) {
+ // We've re-installed the stub; make sure it's disabled here. If package was
+ // originally enabled, we'll install the compressed version of the application
+ // and re-enable it afterward.
+ synchronized (mPm.mLock) {
disableStubPackage(action, deletedPs, allUserHandles);
}
}
@@ -3200,10 +3187,10 @@ final class InstallPackageHelper {
/**
* Installs a package that's already on the system partition.
*/
- @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+ @GuardedBy("mPm.mInstallLock")
private void installPackageFromSystemLIF(@NonNull String codePathString,
@NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
- boolean writeSettings, int previousAppId)
+ boolean writeSettings)
throws PackageManagerException {
final File codePath = new File(codePathString);
@ParsingPackageUtils.ParseFlags int parseFlags =
@@ -3226,13 +3213,12 @@ final class InstallPackageHelper {
mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
- setPackageInstalledForSystemPackage(pkg, allUserHandles,
- origUserHandles, writeSettings, previousAppId);
+ setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings);
}
private void setPackageInstalledForSystemPackage(@NonNull AndroidPackage pkg,
@NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
- boolean writeSettings, int previousAppId) {
+ boolean writeSettings) {
// writer
synchronized (mPm.mLock) {
PackageSetting ps = mPm.mSettings.getPackageLPr(pkg.getPackageName());
@@ -3266,7 +3252,7 @@ final class InstallPackageHelper {
// The method below will take care of removing obsolete permissions and granting
// install permissions.
- mPm.mPermissionManager.onPackageInstalled(pkg, previousAppId,
+ mPm.mPermissionManager.onPackageInstalled(pkg, Process.INVALID_UID,
PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
UserHandle.USER_ALL);
for (final int userId : allUserHandles) {
@@ -3704,7 +3690,14 @@ final class InstallPackageHelper {
}
disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr(
parsedPackage.getPackageName());
- if (parsedPackage.getSharedUserId() != null && !parsedPackage.isLeavingSharedUid()) {
+
+ boolean ignoreSharedUserId = false;
+ if (installedPkgSetting == null) {
+ // We can directly ignore sharedUserSetting for new installs
+ ignoreSharedUserId = parsedPackage.isLeavingSharedUid();
+ }
+
+ if (!ignoreSharedUserId && parsedPackage.getSharedUserId() != null) {
sharedUserSetting = mPm.mSettings.getSharedUserLPw(
parsedPackage.getSharedUserId(),
0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
diff --git a/services/core/java/com/android/server/pm/InstallParams.java b/services/core/java/com/android/server/pm/InstallParams.java
index 6c80976c0f78..18d2b0c23320 100644
--- a/services/core/java/com/android/server/pm/InstallParams.java
+++ b/services/core/java/com/android/server/pm/InstallParams.java
@@ -289,8 +289,8 @@ final class InstallParams extends HandlerParams {
*/
private int fixUpInstallReason(String installerPackageName, int installerUid,
int installReason) {
- if (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
- == PERMISSION_GRANTED) {
+ if (mPm.snapshotComputer().checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ installerUid) == PERMISSION_GRANTED) {
// If the install is being performed by a system app, we trust that app to have set the
// install reason correctly.
return installReason;
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 742cc0237cec..76b9830cbde9 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -92,6 +92,7 @@ public class Installer extends SystemService {
public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
+ public static final int FLAG_STORAGE_SDK = IInstalld.FLAG_STORAGE_SDK;
public static final int FLAG_CLEAR_CACHE_ONLY = IInstalld.FLAG_CLEAR_CACHE_ONLY;
public static final int FLAG_CLEAR_CODE_CACHE_ONLY = IInstalld.FLAG_CLEAR_CODE_CACHE_ONLY;
@@ -190,12 +191,16 @@ public class Installer extends SystemService {
// We explicitly do NOT set previousAppId because the default value should always be 0.
// Manually override previousAppId after building CreateAppDataArgs for specific behaviors.
static CreateAppDataArgs buildCreateAppDataArgs(String uuid, String packageName,
- int userId, int flags, int appId, String seInfo, int targetSdkVersion) {
+ int userId, int flags, int appId, String seInfo, int targetSdkVersion,
+ boolean usesSdk) {
final CreateAppDataArgs args = new CreateAppDataArgs();
args.uuid = uuid;
args.packageName = packageName;
args.userId = userId;
args.flags = flags;
+ if (usesSdk) {
+ args.flags |= FLAG_STORAGE_SDK;
+ }
args.appId = appId;
args.seInfo = seInfo;
args.targetSdkVersion = targetSdkVersion;
@@ -215,6 +220,8 @@ public class Installer extends SystemService {
if (!checkBeforeRemote()) {
return buildPlaceholderCreateAppDataResult();
}
+ // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+ args.previousAppId = 0;
try {
return mInstalld.createAppData(args);
} catch (Exception e) {
@@ -229,6 +236,10 @@ public class Installer extends SystemService {
Arrays.fill(results, buildPlaceholderCreateAppDataResult());
return results;
}
+ // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+ for (final CreateAppDataArgs arg : args) {
+ arg.previousAppId = 0;
+ }
try {
return mInstalld.createAppDataBatched(args);
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
new file mode 100644
index 000000000000..0ee07b650cf5
--- /dev/null
+++ b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static com.android.server.wm.ActivityInterceptorCallback.INTENT_RESOLVER_ORDERED_ID;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.RemoteException;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.server.LocalServices;
+import com.android.server.wm.ActivityInterceptorCallback;
+import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptorInfo;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+/**
+ * Service to register an {@code ActivityInterceptorCallback} that modifies any {@code Intent}
+ * that's being used to launch a user-space {@code ChooserActivity}, by adding
+ * EXTRA_PERMISSION_TOKEN, a Binder representing a single-use-only permission to invoke the
+ * #startActivityAsCaller() API (which normally isn't available in user-space); and setting the
+ * destination component to the delegated component when appropriate.
+ */
+public final class IntentResolverInterceptor {
+ private static final String TAG = "IntentResolverIntercept";
+
+ private final Context mContext;
+ private boolean mUseDelegateChooser;
+
+ private final ActivityInterceptorCallback mActivityInterceptorCallback =
+ new ActivityInterceptorCallback() {
+ @Nullable
+ @Override
+ public ActivityInterceptResult intercept(ActivityInterceptorInfo info) {
+ if (mUseDelegateChooser && isChooserActivity(info)) {
+ return new ActivityInterceptResult(
+ modifyChooserIntent(info.intent),
+ info.checkedOptions);
+ }
+ return null;
+ }
+ };
+
+ public IntentResolverInterceptor(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Start listening for intents and USE_DELEGATE_CHOOSER property changes.
+ */
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+ public void registerListeners() {
+ LocalServices.getService(ActivityTaskManagerInternal.class)
+ .registerActivityStartInterceptor(INTENT_RESOLVER_ORDERED_ID,
+ mActivityInterceptorCallback);
+
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+ mContext.getMainExecutor(), properties -> updateUseDelegateChooser());
+ updateUseDelegateChooser();
+ }
+
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+ private void updateUseDelegateChooser() {
+ mUseDelegateChooser = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.USE_DELEGATE_CHOOSER,
+ false);
+ }
+
+ private Intent modifyChooserIntent(Intent intent) {
+ intent.setComponent(getUnbundledChooserComponentName());
+ addStartActivityPermissionTokenToIntent(intent, getUnbundledChooserComponentName());
+ return intent;
+ }
+
+ private static boolean isChooserActivity(ActivityInterceptorInfo info) {
+ ComponentName targetComponent = new ComponentName(info.aInfo.packageName, info.aInfo.name);
+
+ return targetComponent.equals(getSystemChooserComponentName())
+ || targetComponent.equals(getUnbundledChooserComponentName());
+ }
+
+ private static Intent addStartActivityPermissionTokenToIntent(
+ Intent intent, ComponentName grantee) {
+ try {
+ intent.putExtra(
+ ActivityTaskManager.EXTRA_PERMISSION_TOKEN,
+ ActivityTaskManager.getService().requestStartActivityPermissionToken(grantee));
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to add permission token to chooser intent");
+ }
+ return intent;
+ }
+
+ private static ComponentName getSystemChooserComponentName() {
+ return new ComponentName("android", "com.android.internal.app.ChooserActivity");
+ }
+
+ private static ComponentName getUnbundledChooserComponentName() {
+ return ComponentName.unflattenFromString(
+ Resources.getSystem().getString(R.string.config_chooserActivity));
+ }
+}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 6b3ce773fb63..5e0fc3bf91e7 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -320,8 +320,12 @@ public class LauncherAppsService extends SystemService {
private PackageInstallerService getPackageInstallerService() {
if (mPackageInstallerService == null) {
- mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService)
- ServiceManager.getService("package")).getPackageInstaller());
+ try {
+ mPackageInstallerService = ((PackageInstallerService) ((IPackageManager)
+ ServiceManager.getService("package")).getPackageInstaller());
+ } catch (RemoteException e) {
+ Slog.wtf(TAG, "Error gettig IPackageInstaller", e);
+ }
}
return mPackageInstallerService;
}
@@ -1109,13 +1113,11 @@ public class LauncherAppsService extends SystemService {
// Note the target activity doesn't have to be exported.
// Flag for bubble
- if (startActivityOptions != null) {
- ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);
- if (options.isApplyActivityFlagsForBubbles()) {
- // Flag for bubble to make behaviour match documentLaunchMode=always.
- intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
- intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- }
+ ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);
+ if (options != null && options.isApplyActivityFlagsForBubbles()) {
+ // Flag for bubble to make behaviour match documentLaunchMode=always.
+ intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
+ intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
}
intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index fe2fe097bdf6..0a193573f701 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -676,7 +676,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
String originatingPackageName = null;
if (params.originatingUid != SessionParams.UID_UNKNOWN
&& params.originatingUid != callingUid) {
- String[] packages = mPm.getPackagesForUid(params.originatingUid);
+ String[] packages = mPm.mIPackageManager.getPackagesForUid(params.originatingUid);
if (packages != null && packages.length > 0) {
// Choose an arbitrary representative package in the case of a shared UID.
originatingPackageName = packages[0];
@@ -727,7 +727,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0
&& !isCalledBySystemOrShell(callingUid)
- && (mPm.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ && (mPm.mIPackageManager.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM)
+ == 0) {
throw new SecurityException(
"Only system apps could use the PackageManager.INSTALL_INSTANT_APP flag.");
}
@@ -1153,7 +1154,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
.setAdmin(callerPackageName)
.write();
} else {
- ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId);
+ ApplicationInfo appInfo = mPm.mIPackageManager
+ .getApplicationInfo(callerPackageName, 0, userId);
if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
null);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ced1c7d136aa..ef7158a80a54 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -817,25 +817,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
// It is safe to access mInstallerUid and mInstallSource without lock
// because they are immutable after sealing.
+ final Computer snapshot = mPm.snapshotComputer();
final boolean isInstallPermissionGranted =
- (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
mInstallerUid) == PackageManager.PERMISSION_GRANTED);
final boolean isSelfUpdatePermissionGranted =
- (mPm.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES,
+ (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES,
mInstallerUid) == PackageManager.PERMISSION_GRANTED);
final boolean isUpdatePermissionGranted =
- (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
+ (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
mInstallerUid) == PackageManager.PERMISSION_GRANTED);
- final boolean isUpdateWithoutUserActionPermissionGranted = (mPm.checkUidPermission(
+ final boolean isUpdateWithoutUserActionPermissionGranted = (snapshot.checkUidPermission(
android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
- final boolean isInstallDpcPackagesPermissionGranted = (mPm.checkUidPermission(
+ final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
- final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
+ final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
final boolean isUpdate = targetPackageUid != -1 || isApexSession();
final InstallSourceInfo existingInstallSourceInfo = isUpdate
- ? mPm.getInstallSourceInfo(packageName)
+ ? snapshot.getInstallSourceInfo(packageName)
: null;
final String existingInstallerPackageName = existingInstallSourceInfo != null
? existingInstallSourceInfo.getInstallingPackageName()
@@ -2009,12 +2010,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public void transfer(String packageName) {
Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
- ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId);
+ final Computer snapshot = mPm.snapshotComputer();
+ ApplicationInfo newOwnerAppInfo = snapshot.getApplicationInfo(packageName, 0, userId);
if (newOwnerAppInfo == null) {
throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
}
- if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission(
+ if (PackageManager.PERMISSION_GRANTED != snapshot.checkUidPermission(
Manifest.permission.INSTALL_PACKAGES, newOwnerAppInfo.uid)) {
throw new SecurityException("Destination package " + packageName + " does not have "
+ "the " + Manifest.permission.INSTALL_PACKAGES + " permission");
@@ -2301,6 +2303,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
});
}
+ private static class InstallResult {
+ public final PackageInstallerSession session;
+ public final Bundle extras;
+ InstallResult(PackageInstallerSession session, Bundle extras) {
+ this.session = session;
+ this.extras = extras;
+ }
+ }
+
/**
* Stages installs and do cleanup accordingly depending on whether the installation is
* successful or not.
@@ -2308,11 +2319,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* @return a future that will be completed when the whole process is completed.
*/
private CompletableFuture<Void> install() {
- return installNonStaged().whenComplete((r, t) -> {
+ List<CompletableFuture<InstallResult>> futures = installNonStaged();
+ CompletableFuture<InstallResult>[] arr = new CompletableFuture[futures.size()];
+ return CompletableFuture.allOf(futures.toArray(arr)).whenComplete((r, t) -> {
if (t == null) {
setSessionApplied();
- dispatchSessionFinished(INSTALL_SUCCEEDED, "Session installed", null);
- maybeFinishChildSessions(INSTALL_SUCCEEDED, "Session installed");
+ for (CompletableFuture<InstallResult> f : futures) {
+ InstallResult result = f.join();
+ result.session.dispatchSessionFinished(
+ INSTALL_SUCCEEDED, "Session installed", result.extras);
+ }
} else {
PackageManagerException e = (PackageManagerException) t.getCause();
setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
@@ -2326,13 +2342,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
/**
* Stages sessions (including child sessions if any) for install.
*
- * @return a future that will be completed when the whole session is completed (could be
- * success or failure).
+ * @return a list of futures to indicate the install results of each session.
*/
- private CompletableFuture<Void> installNonStaged() {
+ private List<CompletableFuture<InstallResult>> installNonStaged() {
try {
- List<CompletableFuture<Void>> futures = new ArrayList<>();
- CompletableFuture<Void> future = new CompletableFuture<>();
+ List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
+ CompletableFuture<InstallResult> future = new CompletableFuture<>();
futures.add(future);
final InstallParams installingSession = makeInstallParams(future);
if (isMultiPackage()) {
@@ -2354,12 +2369,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
installingSession.installStage();
}
- CompletableFuture<Void>[] arr = new CompletableFuture[futures.size()];
- return CompletableFuture.allOf(futures.toArray(arr));
+ return futures;
} catch (PackageManagerException e) {
- CompletableFuture<Void> future = new CompletableFuture<>();
- future.completeExceptionally(e);
- return future;
+ List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
+ futures.add(CompletableFuture.failedFuture(e));
+ return futures;
}
}
@@ -2395,7 +2409,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* @param future a future that will be completed when this session is completed.
*/
@Nullable
- private InstallParams makeInstallParams(CompletableFuture<Void> future)
+ private InstallParams makeInstallParams(CompletableFuture<InstallResult> future)
throws PackageManagerException {
synchronized (mLock) {
if (!mSealed) {
@@ -2407,10 +2421,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (isMultiPackage()) {
// Always treat parent session as success for it has nothing to install
- future.complete(null);
+ future.complete(new InstallResult(this, null));
} else if (isApexSession() && params.isStaged) {
// Staged apex sessions have been handled by apexd
- future.complete(null);
+ future.complete(new InstallResult(this, null));
return null;
}
@@ -2424,7 +2438,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
if (returnCode == INSTALL_SUCCEEDED) {
- future.complete(null);
+ future.complete(new InstallResult(PackageInstallerSession.this, extras));
} else {
future.completeExceptionally(new PackageManagerException(returnCode, msg));
}
@@ -2497,7 +2511,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// Package didn't install; no valid uid
packageUid = Process.INVALID_UID;
} else {
- packageUid = mPm.getPackageUid(packageName, 0, userId);
+ packageUid = mPm.snapshotComputer().getPackageUid(packageName, 0, userId);
}
FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLER_V2_REPORTED,
isIncrementalInstallation(),
@@ -2655,7 +2669,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mResolvedStagedFiles.clear();
mResolvedInheritedFiles.clear();
- final PackageInfo pkgInfo = mPm.getPackageInfo(
+ final PackageInfo pkgInfo = mPm.snapshotComputer().getPackageInfo(
params.appPackageName, PackageManager.GET_SIGNATURES
| PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES /*flags*/, userId);
@@ -2848,6 +2862,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
inheritFileLocked(mResolvedBaseFile);
// Collect the requiredSplitTypes from base
CollectionUtils.addAll(requiredSplitTypes, existing.getBaseRequiredSplitTypes());
+ } else {
+ // Installing base.apk. Make sure the app is restarted.
+ params.setDontKillApp(false);
}
// Inherit splits if not overridden.
@@ -3544,6 +3561,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
@Override
+ public int getInstallFlags() {
+ return params.installFlags;
+ }
+
+ @Override
public DataLoaderParamsParcel getDataLoaderParams() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null;
@@ -3766,8 +3788,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
};
try {
- final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0,
- userId);
+ final PackageInfo pkgInfo = mPm.snapshotComputer()
+ .getPackageInfo(this.params.appPackageName, 0, userId);
final File inheritedDir =
(pkgInfo != null && pkgInfo.applicationInfo != null) ? new File(
pkgInfo.applicationInfo.getCodePath()).getParentFile() : null;
@@ -4512,8 +4534,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
final String installerAttributionTag = readStringAttribute(in,
ATTR_INSTALLER_ATTRIBUTION_TAG);
- final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.getPackageUid(
- installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
+ final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.snapshotComputer()
+ .getPackageUid(installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ userId));
final String installInitiatingPackageName =
readStringAttribute(in, ATTR_INITIATING_PACKAGE_NAME);
final String installOriginatingPackageName =
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java b/services/core/java/com/android/server/pm/PackageManagerLocal.java
index aacc6939cf74..7b76567fcc6e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java
+++ b/services/core/java/com/android/server/pm/PackageManagerLocal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 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,13 +14,18 @@
* limitations under the License.
*/
-package com.android.systemui.dagger;
+package com.android.server.pm;
-import dagger.Module;
+import android.annotation.SystemApi;
/**
- * Dagger module for including the WMComponent.
+ * In-process API for server side PackageManager related infrastructure.
+ *
+ * For now, avoiding adding methods that rely on package data until we solve the snapshot
+ * consistency problem.
+ *
+ * @hide
*/
-@Module(subcomponents = {SysUIComponent.class})
-public abstract class SysUISubcomponentModule {
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public interface PackageManagerLocal {
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerNative.java b/services/core/java/com/android/server/pm/PackageManagerNative.java
index 37daf112aa69..9a43008acfdf 100644
--- a/services/core/java/com/android/server/pm/PackageManagerNative.java
+++ b/services/core/java/com/android/server/pm/PackageManagerNative.java
@@ -71,7 +71,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public String[] getAllPackages() {
- return mPm.getAllPackages().toArray(new String[0]);
+ return mPm.snapshotComputer().getAllPackages().toArray(new String[0]);
}
@Override
@@ -82,7 +82,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
if (uids == null || uids.length == 0) {
return null;
}
- names = mPm.getNamesForUids(uids);
+ names = mPm.snapshotComputer().getNamesForUids(uids);
results = (names != null) ? names : new String[uids.length];
// massage results so they can be parsed by the native binder
for (int i = results.length - 1; i >= 0; --i) {
@@ -104,13 +104,14 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
// NB: this differentiates between preloads and sideloads
@Override
public String getInstallerForPackage(String packageName) throws RemoteException {
- final String installerName = mPm.getInstallerPackageName(packageName);
+ final Computer snapshot = mPm.snapshotComputer();
+ final String installerName = snapshot.getInstallerPackageName(packageName);
if (!TextUtils.isEmpty(installerName)) {
return installerName;
}
// differentiate between preload and sideload
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
- ApplicationInfo appInfo = mPm.getApplicationInfo(packageName,
+ ApplicationInfo appInfo = snapshot.getApplicationInfo(packageName,
/*flags*/ 0,
/*userId*/ callingUser);
if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -123,7 +124,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
public long getVersionCodeForPackage(String packageName) throws RemoteException {
try {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
- PackageInfo pInfo = mPm.getPackageInfo(packageName, 0, callingUser);
+ PackageInfo pInfo = mPm.snapshotComputer()
+ .getPackageInfo(packageName, 0, callingUser);
if (pInfo != null) {
return pInfo.getLongVersionCode();
}
@@ -134,7 +136,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
- int targetSdk = mPm.getTargetSdkVersion(packageName);
+ int targetSdk = mPm.snapshotComputer().getTargetSdkVersion(packageName);
if (targetSdk != -1) {
return targetSdk;
}
@@ -145,7 +147,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public boolean isPackageDebuggable(String packageName) throws RemoteException {
int callingUser = UserHandle.getCallingUserId();
- ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, 0, callingUser);
+ ApplicationInfo appInfo = mPm.snapshotComputer()
+ .getApplicationInfo(packageName, 0, callingUser);
if (appInfo != null) {
return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
}
@@ -157,9 +160,10 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
+ final Computer snapshot = mPm.snapshotComputer();
boolean[] results = new boolean[packageNames.length];
for (int i = results.length - 1; i >= 0; --i) {
- ApplicationInfo appInfo = mPm.getApplicationInfo(packageNames[i], 0, callingUser);
+ ApplicationInfo appInfo = snapshot.getApplicationInfo(packageNames[i], 0, callingUser);
results[i] = appInfo != null && appInfo.isAudioPlaybackCaptureAllowed();
}
return results;
@@ -168,7 +172,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public int getLocationFlags(String packageName) throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
- ApplicationInfo appInfo = mPm.getApplicationInfo(packageName,
+ ApplicationInfo appInfo = mPm.snapshotComputer().getApplicationInfo(packageName,
/*flags*/ 0,
/*userId*/ callingUser);
if (appInfo == null) {
@@ -188,7 +192,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public boolean hasSha256SigningCertificate(String packageName, byte[] certificate)
throws RemoteException {
- return mPm.hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256);
+ return mPm.snapshotComputer()
+ .hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ee49a5184e7f..e20a861e2eae 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -105,11 +105,6 @@ import android.content.pm.PackageInfoLite;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ComponentEnabledSetting;
-import android.content.pm.PackageManager.ComponentType;
-import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
-import android.content.pm.PackageManager.ModuleInfoFlags;
-import android.content.pm.PackageManager.Property;
-import android.content.pm.PackageManager.PropertyLocation;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackagePartitions;
import android.content.pm.ParceledListSlice;
@@ -203,6 +198,7 @@ import com.android.internal.util.Preconditions;
import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
+import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.PackageWatchdog;
@@ -217,6 +213,7 @@ import com.android.server.pm.Settings.VersionInfo;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.ArtUtils;
import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.PackageInfoUtils;
@@ -333,8 +330,8 @@ import java.util.function.Consumer;
* $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
* </pre>
*/
-public class PackageManagerService extends IPackageManager.Stub
- implements PackageSender, TestUtilityService {
+public class PackageManagerService implements PackageSender, TestUtilityService {
+
static final String TAG = "PackageManager";
public static final boolean DEBUG_SETTINGS = false;
static final boolean DEBUG_PREFERRED = false;
@@ -647,6 +644,8 @@ public class PackageManagerService extends IPackageManager.Stub
*/
boolean mPromoteSystemApps;
+ // TODO: Make IPackageManager reference private to hide discouraged APIs
+ final IPackageManagerImpl mIPackageManager;
private final PackageManagerInternal mPmInternal;
private final TestUtilityService mTestUtilityService;
@@ -957,6 +956,7 @@ public class PackageManagerService extends IPackageManager.Stub
private final ResolveIntentHelper mResolveIntentHelper;
private final DexOptHelper mDexOptHelper;
private final SuspendPackageHelper mSuspendPackageHelper;
+ private final IntentResolverInterceptor mIntentResolverInterceptor;
/**
* Invalidate the package info cache, which includes updating the cached computer.
@@ -1058,7 +1058,7 @@ public class PackageManagerService extends IPackageManager.Stub
private volatile Computer mSnapshotComputer;
// A trampoline that directs callers to either the live or snapshot computer.
- private final ComputerTracker mComputer = new ComputerTracker(this);
+ final ComputerTracker mComputer = new ComputerTracker(this);
// If true, the snapshot is invalid (stale). The attribute is static since it may be
// set from outside classes. The attribute may be set to true anywhere, although it
@@ -1166,15 +1166,6 @@ public class PackageManagerService extends IPackageManager.Stub
onChange(null);
}
- @Override
- public void notifyPackagesReplacedReceived(String[] packages) {
- Computer computer = snapshotComputer();
- ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
- for (int index = 0; index < packagesToNotify.size(); index++) {
- notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
- }
- }
-
void notifyInstallObserver(String packageName, boolean killApp) {
final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
killApp ? mPendingKillInstallObservers.remove(packageName)
@@ -1231,16 +1222,6 @@ public class PackageManagerService extends IPackageManager.Stub
PRUNE_UNUSED_SHARED_LIBRARIES_DELAY);
}
- @Override
- public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
- @Nullable List trustedInstallers,
- @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
- requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
- onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
- mInjector.getBackgroundHandler());
- }
-
/**
* Requests checksums for the APK file.
* See {@link PackageInstaller.Session#requestChecksums} for details.
@@ -1288,7 +1269,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (applicationInfo == null) {
throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
}
- final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName);
+ final InstallSourceInfo installSourceInfo =
+ mIPackageManager.getInstallSourceInfo(packageName);
final String installerPackageName =
installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null;
@@ -1430,9 +1412,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- public static PackageManagerService main(Context context, Installer installer,
- @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
- boolean onlyCore) {
+ public static Pair<PackageManagerService, IPackageManager> main(Context context,
+ Installer installer, @NonNull DomainVerificationService domainVerificationService,
+ boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
@@ -1463,10 +1445,10 @@ public class PackageManagerService extends IPackageManager.Stub
(i, pm) -> SystemConfig.getInstance(),
(i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
i.getContext(), "*dexopt*"),
- (i, pm) -> new DexManager(i.getContext(), pm, i.getPackageDexOptimizer(),
+ (i, pm) -> new DexManager(i.getContext(), pm.mIPackageManager,
+ i.getPackageDexOptimizer(), i.getInstaller(), i.getInstallLock()),
+ (i, pm) -> new ArtManagerService(i.getContext(), pm.mIPackageManager,
i.getInstaller(), i.getInstallLock()),
- (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(),
- i.getInstallLock()),
(i, pm) -> ApexManager.getInstance(),
(i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
(i, pm) -> (IncrementalManager)
@@ -1488,7 +1470,7 @@ public class PackageManagerService extends IPackageManager.Stub
i.getContext(), pm, i::getScanningPackageParser),
(i, pm, cn) -> new InstantAppResolverConnection(
i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
- (i, pm) -> new ModuleInfoProvider(i.getContext(), pm),
+ (i, pm) -> new ModuleInfoProvider(i.getContext(), pm.mIPackageManager),
(i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
(i, pm) -> domainVerificationService,
(i, pm) -> {
@@ -1549,10 +1531,11 @@ public class PackageManagerService extends IPackageManager.Stub
selinuxChangeListener);
m.installAllowlistedSystemPackages();
- ServiceManager.addService("package", m);
+ ServiceManager.addService("package", m.mIPackageManager);
final PackageManagerNative pmn = new PackageManagerNative(m);
ServiceManager.addService("package_native", pmn);
- return m;
+ LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl());
+ return Pair.create(m, m.mIPackageManager);
}
/** Install/uninstall system packages for all users based on their user-type, as applicable. */
@@ -1658,6 +1641,7 @@ public class PackageManagerService extends IPackageManager.Stub
mPackageDexOptimizer = testParams.packageDexOptimizer;
mPackageParserCallback = testParams.packageParserCallback;
mPendingBroadcasts = testParams.pendingPackageBroadcasts;
+ mIPackageManager = new IPackageManagerImpl();
mPmInternal = testParams.pmInternal;
mTestUtilityService = testParams.testUtilityService;
mProcessLoggingHandler = testParams.processLoggingHandler;
@@ -1710,6 +1694,8 @@ public class PackageManagerService extends IPackageManager.Stub
mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
+ mIntentResolverInterceptor = null;
+
registerObservers(false);
invalidatePackageInfoCache();
}
@@ -1717,6 +1703,7 @@ public class PackageManagerService extends IPackageManager.Stub
public PackageManagerService(PackageManagerServiceInjector injector, boolean onlyCore,
boolean factoryTest, final String buildFingerprint, final boolean isEngBuild,
final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
+ mIPackageManager = new IPackageManagerImpl();
mIsEngBuild = isEngBuild;
mIsUserDebugBuild = isUserDebugBuild;
mSdkVersion = sdkVersion;
@@ -1768,7 +1755,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean hasFeature(String feature) {
- return PackageManagerService.this.hasSystemFeature(feature, 0);
+ return PackageManagerService.this.mIPackageManager.hasSystemFeature(feature, 0);
}
};
@@ -1995,11 +1982,13 @@ public class PackageManagerService extends IPackageManager.Stub
mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);
mComponentResolver.fixProtectedFilterPriorities(mPmInternal.getSetupWizardPackageName());
- mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
- mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
+ mDefaultTextClassifierPackage = mIPackageManager.getDefaultTextClassifierPackageName();
+ mSystemTextClassifierPackageName =
+ mIPackageManager.getSystemTextClassifierPackageName();
mConfiguratorPackage = getDeviceConfiguratorPackageName();
- mAppPredictionServicePackage = getAppPredictionServicePackageName();
- mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
+ mAppPredictionServicePackage = mIPackageManager.getAppPredictionServicePackageName();
+ mIncidentReportApproverPackage =
+ mIPackageManager.getIncidentReportApproverPackageName();
mRetailDemoPackage = getRetailDemoPackageName();
mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
mRecentsPackage = getRecentsPackageName();
@@ -2154,7 +2143,7 @@ public class PackageManagerService extends IPackageManager.Stub
mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);
mSettings.setPermissionControllerVersion(
- getPackageInfo(mRequiredPermissionControllerPackage, 0,
+ mIPackageManager.getPackageInfo(mRequiredPermissionControllerPackage, 0,
UserHandle.USER_SYSTEM).getLongVersionCode());
// Resolve the sdk sandbox package
@@ -2202,7 +2191,8 @@ public class PackageManagerService extends IPackageManager.Stub
// scanning).
final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
for (int userId : userIds) {
- userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
+ userPackages.put(userId, mIPackageManager.getInstalledPackages(/*flags*/ 0, userId)
+ .getList());
}
mDexManager.load(userPackages);
if (mIsUpgrade) {
@@ -2238,6 +2228,8 @@ public class PackageManagerService extends IPackageManager.Stub
mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
+ mIntentResolverInterceptor = new IntentResolverInterceptor(mContext);
+
Slog.i(TAG, "Fix for b/169414761 is applied");
}
@@ -2253,19 +2245,16 @@ public class PackageManagerService extends IPackageManager.Stub
setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
}
- @Override
public boolean isFirstBoot() {
// allow instant applications
return mFirstBoot;
}
- @Override
public boolean isOnlyCoreApps() {
// allow instant applications
return mOnlyCore;
}
- @Override
public boolean isDeviceUpgrading() {
// allow instant applications
// The system property allows testing ota flow when upgraded to the same image.
@@ -2386,8 +2375,9 @@ public class PackageManagerService extends IPackageManager.Stub
for (int i = 0; i < N; i++) {
final ResolveInfo cur = matches.get(i);
final String packageName = cur.getComponentInfo().packageName;
- if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
- packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
+ if (mIPackageManager.checkPermission(
+ android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, packageName,
+ UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
continue;
}
@@ -2415,8 +2405,9 @@ public class PackageManagerService extends IPackageManager.Stub
for (int i = 0; i < N; i++) {
final ResolveInfo cur = matches.get(i);
final String packageName = cur.getComponentInfo().packageName;
- if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
- packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
+ if (mIPackageManager.checkPermission(
+ android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, packageName,
+ UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "Domain verification agent found but does not hold permission: "
+ packageName);
continue;
@@ -2439,14 +2430,6 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- @Override
- public @Nullable ComponentName getInstantAppResolverComponent() {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return null;
- }
- return getInstantAppResolver();
- }
-
private @Nullable ComponentName getInstantAppResolver() {
final String[] packageArray =
mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
@@ -2536,7 +2519,7 @@ public class PackageManagerService extends IPackageManager.Stub
Iterator<ResolveInfo> iter = matches.iterator();
while (iter.hasNext()) {
final ResolveInfo rInfo = iter.next();
- if (checkPermission(
+ if (mIPackageManager.checkPermission(
Manifest.permission.INSTALL_PACKAGES,
rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) {
continue;
@@ -2567,18 +2550,18 @@ public class PackageManagerService extends IPackageManager.Stub
return matches.get(0).getComponentInfo().getComponentName();
}
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- return super.onTransact(code, data, reply, flags);
- } catch (RuntimeException e) {
- if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)
- && !(e instanceof ParcelableException)) {
- Slog.wtf(TAG, "Package Manager Unexpected Exception", e);
- }
- throw e;
- }
+ /**
+ * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
+ */
+ boolean shouldFilterApplication(
+ @Nullable PackageStateInternal ps, int callingUid, int userId) {
+ return mComputer.shouldFilterApplication(
+ ps, callingUid, userId);
+ }
+
+ private @PackageStartability int getPackageStartability(String packageName,
+ int callingUid, int userId) {
+ return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId);
}
/**
@@ -2604,118 +2587,11 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.generatePackageInfo(ps, flags, userId);
}
- @Override
- public void checkPackageStartable(String packageName, int userId) {
- final int callingUid = Binder.getCallingUid();
- if (getInstantAppPackageName(callingUid) != null) {
- throw new SecurityException("Instant applications don't have access to this method");
- }
- if (!mUserManager.exists(userId)) {
- throw new SecurityException("User doesn't exist");
- }
- enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
- switch (getPackageStartability(packageName, callingUid, userId)) {
- case PACKAGE_STARTABILITY_NOT_FOUND:
- throw new SecurityException("Package " + packageName + " was not found!");
- case PACKAGE_STARTABILITY_NOT_SYSTEM:
- throw new SecurityException("Package " + packageName + " not a system app!");
- case PACKAGE_STARTABILITY_FROZEN:
- throw new SecurityException("Package " + packageName + " is currently frozen!");
- case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
- throw new SecurityException("Package " + packageName + " is not encryption aware!");
- case PACKAGE_STARTABILITY_OK:
- default:
- }
- }
-
- private @PackageStartability int getPackageStartability(String packageName,
- int callingUid, int userId) {
- return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId);
- }
-
- @Override
- public boolean isPackageAvailable(String packageName, int userId) {
- return mComputer.isPackageAvailable(packageName, userId);
- }
-
- @Override
- public PackageInfo getPackageInfo(String packageName,
- @PackageManager.PackageInfoFlagsBits long flags, int userId) {
- return mComputer.getPackageInfo(packageName, flags, userId);
- }
-
- @Override
- public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
- @PackageManager.PackageInfoFlagsBits long flags, int userId) {
- return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(),
- versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
- }
-
- /**
- * Returns whether or not access to the application should be filtered.
- * <p>
- * Access may be limited based upon whether the calling or target applications
- * are instant applications.
- *
- * @see #canViewInstantApps(int, int)
- */
- private boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
- @Nullable ComponentName component, @ComponentType int componentType, int userId) {
- return mComputer.shouldFilterApplication(ps, callingUid,
- component, componentType, userId);
- }
-
- /**
- * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
- */
- boolean shouldFilterApplication(
- @Nullable PackageStateInternal ps, int callingUid, int userId) {
- return mComputer.shouldFilterApplication(
- ps, callingUid, userId);
- }
-
- /**
- * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
- */
- private boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
- int userId) {
- return mComputer.shouldFilterApplication(sus, callingUid, userId);
- }
-
- private boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
- int userId, @PackageManager.ComponentInfoFlagsBits long flags) {
- return mComputer.filterSharedLibPackage(ps, uid, userId, flags);
- }
-
- @Override
- public String[] currentToCanonicalPackageNames(String[] names) {
- return mComputer.currentToCanonicalPackageNames(names);
- }
-
- @Override
- public String[] canonicalToCurrentPackageNames(String[] names) {
- return mComputer.canonicalToCurrentPackageNames(names);
- }
-
- @Override
- public int getPackageUid(@NonNull String packageName,
- @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
- return mComputer.getPackageUid(packageName, flags, userId);
- }
-
int getPackageUidInternal(String packageName,
@PackageManager.PackageInfoFlagsBits long flags, int userId, int callingUid) {
return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid);
}
- @Override
- public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags,
- int userId) {
- return mComputer.getPackageGids(packageName, flags, userId);
- }
-
- // NOTE: Can't remove due to unsupported app usage
- @Override
public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
// Because this is accessed via the package manager service AIDL,
// go through the permission manager service AIDL
@@ -2723,18 +2599,6 @@ public class PackageManagerService extends IPackageManager.Stub
.getPermissionGroupInfo(groupName, flags);
}
- private ApplicationInfo generateApplicationInfoFromSettings(String packageName,
- @PackageManager.ApplicationInfoFlagsBits long flags, int filterCallingUid, int userId) {
- return mComputer.generateApplicationInfoFromSettings(packageName, flags, filterCallingUid,
- userId);
- }
-
- @Override
- public ApplicationInfo getApplicationInfo(String packageName,
- @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
- return mComputer.getApplicationInfo(packageName, flags, userId);
- }
-
/**
* Important: The provided filterCallingUid is used exclusively to filter out applications
* that can be seen based on user state. It's typically the original caller uid prior
@@ -2748,61 +2612,6 @@ public class PackageManagerService extends IPackageManager.Stub
filterCallingUid, userId);
}
- @Override
- public void deletePreloadsFileCache() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
- "deletePreloadsFileCache");
- File dir = Environment.getDataPreloadsFileCacheDirectory();
- Slog.i(TAG, "Deleting preloaded file cache " + dir);
- FileUtils.deleteContents(dir);
- }
-
- @Override
- public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
- final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_CACHE, null);
- mHandler.post(() -> {
- boolean success = false;
- try {
- freeStorage(volumeUuid, freeStorageSize, flags);
- success = true;
- } catch (IOException e) {
- Slog.w(TAG, e);
- }
- if (observer != null) {
- try {
- observer.onRemoveCompleted(null, success);
- } catch (RemoteException e) {
- Slog.w(TAG, e);
- }
- }
- });
- }
-
- @Override
- public void freeStorage(final String volumeUuid, final long freeStorageSize,
- final @StorageManager.AllocateFlags int flags, final IntentSender pi) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_CACHE, TAG);
- mHandler.post(() -> {
- boolean success = false;
- try {
- freeStorage(volumeUuid, freeStorageSize, flags);
- success = true;
- } catch (IOException e) {
- Slog.w(TAG, e);
- }
- if (pi != null) {
- try {
- pi.sendIntent(null, success ? 1 : 0, null, null, null);
- } catch (SendIntentException e) {
- Slog.w(TAG, e);
- }
- }
- });
- }
-
/**
* Blocking call to clear all cached app data above quota.
*/
@@ -2839,7 +2648,7 @@ public class PackageManagerService extends IPackageManager.Stub
// 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
if (internalVolume && (aggressive || SystemProperties
.getBoolean("persist.sys.preloads.file_cache_expired", false))) {
- deletePreloadsFileCache();
+ mIPackageManager.deletePreloadsFileCache();
if (file.getUsableSpace() >= bytes) return;
}
@@ -2978,17 +2787,6 @@ public class PackageManagerService extends IPackageManager.Stub
wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
}
- @Override
- public int getTargetSdkVersion(@NonNull String packageName) {
- return mComputer.getTargetSdkVersion(packageName);
- }
-
- @Override
- public ActivityInfo getActivityInfo(ComponentName component,
- @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
- return mComputer.getActivityInfo(component, flags, userId);
- }
-
/**
* Important: The provided filterCallingUid is used exclusively to filter out activities
* that can be seen based on user state. It's typically the original caller uid prior
@@ -3001,33 +2799,6 @@ public class PackageManagerService extends IPackageManager.Stub
filterCallingUid, userId);
}
- @Override
- public boolean activitySupportsIntent(ComponentName component, Intent intent,
- String resolvedType) {
- return mComputer.activitySupportsIntent(mResolveComponentName, component, intent,
- resolvedType);
- }
-
- @Override
- public ActivityInfo getReceiverInfo(ComponentName component,
- @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
- return mComputer.getReceiverInfo(component, flags, userId);
- }
-
- @Override
- public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
- @PackageManager.PackageInfoFlagsBits long flags, int userId) {
- return mComputer.getSharedLibraries(packageName, flags, userId);
- }
-
- @Nullable
- @Override
- public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
- @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
- @NonNull int userId) {
- return mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
- }
-
@Nullable
List<VersionedPackage> getPackagesUsingSharedLibrary(
SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlagsBits long flags,
@@ -3035,95 +2806,15 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
}
- @Nullable
- @Override
- public ServiceInfo getServiceInfo(@NonNull ComponentName component,
- @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
- return mComputer.getServiceInfo(component, flags, userId);
- }
-
- @Nullable
- @Override
- public ProviderInfo getProviderInfo(@NonNull ComponentName component,
- @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
- return mComputer.getProviderInfo(component, flags, userId);
- }
-
- @Override
- public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
+ public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) {
return mModuleInfoProvider.getModuleInfo(packageName, flags);
}
- @Override
- public List<ModuleInfo> getInstalledModules(int flags) {
- return mModuleInfoProvider.getInstalledModules(flags);
- }
-
- @Nullable
- @Override
- public String[] getSystemSharedLibraryNames() {
- return mComputer.getSystemSharedLibraryNames();
- }
-
- @Override
- public @NonNull String getServicesSystemSharedLibraryPackageName() {
- return mServicesExtensionPackageName;
- }
-
- @Override
- public @NonNull String getSharedSystemSharedLibraryPackageName() {
- return mSharedSystemSharedLibraryPackageName;
- }
-
@GuardedBy("mLock")
void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
mChangedPackagesTracker.updateSequenceNumber(pkgSetting.getPackageName(), userList);
}
- @Override
- public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
- final int callingUid = Binder.getCallingUid();
- if (getInstantAppPackageName(callingUid) != null) {
- return null;
- }
- if (!mUserManager.exists(userId)) {
- return null;
- }
- enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
- final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages(
- sequenceNumber, userId);
-
- if (changedPackages != null) {
- final List<String> packageNames = changedPackages.getPackageNames();
- for (int index = packageNames.size() - 1; index >= 0; index--) {
- // Filter out the changes if the calling package should not be able to see it.
- final PackageSetting ps = mSettings.getPackageLPr(packageNames.get(index));
- if (shouldFilterApplication(ps, callingUid, userId)) {
- packageNames.remove(index);
- }
- }
- }
-
- return changedPackages;
- }
-
- @Override
- public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
- // allow instant applications
- ArrayList<FeatureInfo> res;
- synchronized (mAvailableFeatures) {
- res = new ArrayList<>(mAvailableFeatures.size() + 1);
- res.addAll(mAvailableFeatures.values());
- }
- final FeatureInfo fi = new FeatureInfo();
- fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
- FeatureInfo.GL_ES_VERSION_UNDEFINED);
- res.add(fi);
-
- return new ParceledListSlice<>(res);
- }
-
- @Override
public boolean hasSystemFeature(String name, int version) {
// allow instant applications
synchronized (mAvailableFeatures) {
@@ -3137,29 +2828,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
// NOTE: Can't remove due to unsupported app usage
- @Override
public int checkPermission(String permName, String pkgName, int userId) {
return mPermissionManager.checkPermission(pkgName, permName, userId);
}
- // NOTE: Can't remove without a major refactor. Keep around for now.
- @Override
- public int checkUidPermission(String permName, int uid) {
- return mComputer.checkUidPermission(permName, uid);
- }
-
- @Override
- public String getPermissionControllerPackageName() {
- final int callingUid = Binder.getCallingUid();
- if (mComputer.getPackageStateFiltered(mRequiredPermissionControllerPackage,
- callingUid, UserHandle.getUserId(callingUid)) != null) {
- return mRequiredPermissionControllerPackage;
- }
-
- throw new IllegalStateException("PermissionController is not found");
- }
-
- @Override
public String getSdkSandboxPackageName() {
return mRequiredSdkSandboxPackage;
}
@@ -3168,171 +2840,6 @@ public class PackageManagerService extends IPackageManager.Stub
return mRequiredInstallerPackage;
}
- // NOTE: Can't remove due to unsupported app usage
- @Override
- public boolean addPermission(PermissionInfo info) {
- // Because this is accessed via the package manager service AIDL,
- // go through the permission manager service AIDL
- return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
- }
-
- // NOTE: Can't remove due to unsupported app usage
- @Override
- public boolean addPermissionAsync(PermissionInfo info) {
- // Because this is accessed via the package manager service AIDL,
- // go through the permission manager service AIDL
- return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
- }
-
- // NOTE: Can't remove due to unsupported app usage
- @Override
- public void removePermission(String permName) {
- // Because this is accessed via the package manager service AIDL,
- // go through the permission manager service AIDL
- mContext.getSystemService(PermissionManager.class).removePermission(permName);
- }
-
- // NOTE: Can't remove due to unsupported app usage
- @Override
- public void grantRuntimePermission(String packageName, String permName, final int userId) {
- // Because this is accessed via the package manager service AIDL,
- // go through the permission manager service AIDL
- mContext.getSystemService(PermissionManager.class)
- .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
- }
-
- @Override
- public boolean isProtectedBroadcast(String actionName) {
- if (actionName != null) {
- // TODO: remove these terrible hacks
- if (actionName.startsWith("android.net.netmon.lingerExpired")
- || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
- || actionName.startsWith("com.android.internal.telephony.data-reconnect")
- || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
- return true;
- }
- }
- // allow instant applications
- synchronized (mProtectedBroadcasts) {
- return mProtectedBroadcasts.contains(actionName);
- }
- }
-
- @Override
- public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
- return mComputer.checkSignatures(pkg1, pkg2);
- }
-
- @Override
- public int checkUidSignatures(int uid1, int uid2) {
- return mComputer.checkUidSignatures(uid1, uid2);
- }
-
- @Override
- public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
- @PackageManager.CertificateInputType int type) {
- return mComputer.hasSigningCertificate(packageName, certificate, type);
- }
-
- @Override
- public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
- @PackageManager.CertificateInputType int type) {
- return mComputer.hasUidSigningCertificate(uid, certificate, type);
- }
-
- @Override
- public List<String> getAllPackages() {
- return mComputer.getAllPackages();
- }
-
- /**
- * <em>IMPORTANT:</em> Not all packages returned by this method may be known
- * to the system. There are two conditions in which this may occur:
- * <ol>
- * <li>The package is on adoptable storage and the device has been removed</li>
- * <li>The package is being removed and the internal structures are partially updated</li>
- * </ol>
- * The second is an artifact of the current data structures and should be fixed. See
- * b/111075456 for one such instance.
- * This binder API is cached. If the algorithm in this method changes,
- * or if the underlying objecs (as returned by getSettingLPr()) change
- * then the logic that invalidates the cache must be revisited. See
- * calls to invalidateGetPackagesForUidCache() to locate the points at
- * which the cache is invalidated.
- */
- @Override
- public String[] getPackagesForUid(int uid) {
- final int callingUid = Binder.getCallingUid();
- final int userId = UserHandle.getUserId(uid);
- enforceCrossUserOrProfilePermission(callingUid, userId,
- /* requireFullPermission */ false,
- /* checkShell */ false, "getPackagesForUid");
- return mComputer.getPackagesForUid(uid);
- }
-
- @Nullable
- @Override
- public String getNameForUid(int uid) {
- return mComputer.getNameForUid(uid);
- }
-
- @Nullable
- @Override
- public String[] getNamesForUids(@NonNull int[] uids) {
- return mComputer.getNamesForUids(uids);
- }
-
- @Override
- public int getUidForSharedUser(@NonNull String sharedUserName) {
- return mComputer.getUidForSharedUser(sharedUserName);
- }
-
- @Override
- public int getFlagsForUid(int uid) {
- return mComputer.getFlagsForUid(uid);
- }
-
- @Override
- public int getPrivateFlagsForUid(int uid) {
- return mComputer.getPrivateFlagsForUid(uid);
- }
-
- @Override
- public boolean isUidPrivileged(int uid) {
- return mComputer.isUidPrivileged(uid);
- }
-
- // NOTE: Can't remove due to unsupported app usage
- @NonNull
- @Override
- public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
- return mComputer.getAppOpPermissionPackages(permissionName);
- }
-
- @Override
- public ResolveInfo resolveIntent(Intent intent, String resolvedType,
- @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType,
- flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
- }
-
- @Override
- public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
- return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId);
- }
-
- @Override
- public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
- IntentFilter filter, int match, ComponentName activity) {
- mPreferredActivityHelper.setLastChosenActivity(intent, resolvedType, flags,
- new WatchedIntentFilter(filter), match, activity);
- }
-
- @Override
- public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
- return mPreferredActivityHelper.getLastChosenActivity(intent, resolvedType, flags);
- }
-
private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
Intent origIntent, String resolvedType, String callingPackage,
@Nullable String callingFeatureId, boolean isRequesterInstantApp,
@@ -3387,38 +2894,6 @@ public class PackageManagerService extends IPackageManager.Stub
removeMatches, debug, userId, queryMayBeFiltered);
}
- /*
- * Returns if intent can be forwarded from the sourceUserId to the targetUserId
- */
- @Override
- public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
- @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
- return mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
- }
-
- private UserInfo getProfileParent(int userId) {
- return mComputer.getProfileParent(userId);
- }
-
- private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
- String resolvedType, int userId) {
- return mComputer.getMatchingCrossProfileIntentFilters(intent,
- resolvedType, userId);
- }
-
- @Override
- public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
-
- return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent,
- resolvedType, flags, userId));
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
/**
* Returns the package name of the calling Uid if it's an instant app. If it isn't
* instant, returns {@code null}.
@@ -3427,36 +2902,11 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.getInstantAppPackageName(callingUid);
}
- @Override
- public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
- Intent[] specifics, String[] specificTypes, Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
- snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags,
- userId));
- }
-
- @Override
- public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(@NonNull Computer snapshot,
+ Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+ @UserIdInt int userId) {
return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
- snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid()));
- }
-
- @Override
- public ResolveInfo resolveService(Intent intent, String resolvedType,
- @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- final int callingUid = Binder.getCallingUid();
- return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType,
- flags, userId, callingUid);
- }
-
- @Override
- public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- final int callingUid = Binder.getCallingUid();
- return new ParceledListSlice<>(queryIntentServicesInternal(
- intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
+ snapshot, intent, resolvedType, flags, userId, Binder.getCallingUid()));
}
@NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
@@ -3467,163 +2917,16 @@ public class PackageManagerService extends IPackageManager.Stub
includeInstantApps);
}
- @Override
- public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
- snapshotComputer(), intent, resolvedType, flags, userId));
- }
-
- @Override
- public ParceledListSlice<PackageInfo> getInstalledPackages(
- @PackageManager.PackageInfoFlagsBits long flags, int userId) {
- return mComputer.getInstalledPackages(flags, userId);
- }
-
- @Override
- public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
- @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
- @UserIdInt int userId) {
- return mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
- }
-
- @Override
- public ParceledListSlice<ApplicationInfo> getInstalledApplications(
- @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
- final int callingUid = Binder.getCallingUid();
- return new ParceledListSlice<>(
- mComputer.getInstalledApplications(flags, userId, callingUid));
- }
-
- @Override
- public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
- if (HIDE_EPHEMERAL_APIS) {
- return null;
- }
- if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
- "getEphemeralApplications");
- }
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
- false /* checkShell */, "getEphemeralApplications");
-
- Computer computer = snapshotComputer();
- List<InstantAppInfo> instantApps = mInstantAppRegistry.getInstantApps(computer, userId);
- if (instantApps != null) {
- return new ParceledListSlice<>(instantApps);
- }
- return null;
- }
-
- @Override
- public boolean isInstantApp(String packageName, int userId) {
- return mComputer.isInstantApp(packageName, userId);
- }
-
private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
int callingUid) {
return mComputer.isInstantAppInternal(packageName, userId,
callingUid);
}
- @Override
- public byte[] getInstantAppCookie(String packageName, int userId) {
- if (HIDE_EPHEMERAL_APIS) {
- return null;
- }
-
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
- false /* checkShell */, "getInstantAppCookie");
- if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
- return null;
- }
- PackageStateInternal packageState = getPackageStateInternal(packageName);
- if (packageState == null || packageState.getPkg() == null) {
- return null;
- }
- return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId);
- }
-
- @Override
- public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
- if (HIDE_EPHEMERAL_APIS) {
- return true;
- }
-
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
- true /* checkShell */, "setInstantAppCookie");
- if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
- return false;
- }
-
- PackageStateInternal packageState = getPackageStateInternal(packageName);
- if (packageState == null || packageState.getPkg() == null) {
- return false;
- }
- return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie,
- mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId);
- }
-
- @Override
- public Bitmap getInstantAppIcon(String packageName, int userId) {
- if (HIDE_EPHEMERAL_APIS) {
- return null;
- }
-
- if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
- "getInstantAppIcon");
- }
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
- false /* checkShell */, "getInstantAppIcon");
-
- return mInstantAppRegistry.getInstantAppIcon(packageName, userId);
- }
-
boolean isCallerSameApp(String packageName, int uid) {
return mComputer.isCallerSameApp(packageName, uid);
}
- @Override
- public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return ParceledListSlice.emptyList();
- }
- return new ParceledListSlice<>(mComputer.getPersistentApplications(mSafeMode, flags));
- }
-
- @Override
- public ProviderInfo resolveContentProvider(String name,
- @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid());
- }
-
- @Deprecated
- public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
- mComputer.querySyncProviders(mSafeMode, outNames, outInfo);
- }
-
- @NonNull
- @Override
- public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
- int uid, @PackageManager.ComponentInfoFlagsBits long flags,
- @Nullable String metaDataKey) {
- return mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
- }
-
- @Nullable
- @Override
- public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
- return mComputer.getInstrumentationInfo(component, flags);
- }
-
- @NonNull
- @Override
- public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
- @NonNull String targetPackage, int flags) {
- return mComputer.queryInstrumentation(targetPackage, flags);
- }
-
public static void reportSettingsProblem(int priority, String msg) {
logCriticalInfo(priority, msg);
}
@@ -3673,7 +2976,6 @@ public class PackageManagerService extends IPackageManager.Stub
requireFullPermission, checkShell, message);
}
- @Override
public void performFstrimIfNeeded() {
PackageManagerServiceUtils.enforceSystemOrRoot("Only the system can request fstrim");
@@ -3715,28 +3017,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
public void updatePackagesIfNeeded() {
mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
}
- @Override
- public void notifyPackageUse(String packageName, int reason) {
- final int callingUid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(callingUid);
- Computer computer = snapshotComputer();
- final boolean notify;
- if (getInstantAppPackageName(callingUid) != null) {
- notify = isCallerSameApp(packageName, callingUid);
- } else {
- notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID);
- }
- if (!notify) {
- return;
- }
-
- notifyPackageUseInternal(packageName, reason);
- }
private void notifyPackageUseInternal(String packageName, int reason) {
long time = System.currentTimeMillis();
@@ -3745,103 +3029,6 @@ public class PackageManagerService extends IPackageManager.Stub
});
}
- @Override
- public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
- String loaderIsa) {
- int callingUid = Binder.getCallingUid();
- if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) {
- Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid="
- + callingUid);
- // Do not record dex loads from processes pretending to be system server.
- // Only the system server should be assigned the package "android", so reject calls
- // that don't satisfy the constraint.
- //
- // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
- // craft calls to this API and pretend to be system server. Doing so poses no particular
- // danger for dex load reporting or later dexopt, however it is a sensible check to do
- // in order to verify the expectations.
- return;
- }
-
- int userId = UserHandle.getCallingUserId();
- ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
- if (ai == null) {
- Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
- + loadingPackageName + ", user=" + userId);
- return;
- }
- mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
- Process.isIsolated(callingUid));
- }
-
- @Override
- public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
- IDexModuleRegisterCallback callback) {
- int userId = UserHandle.getCallingUserId();
- ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
- DexManager.RegisterDexModuleResult result;
- if (ai == null) {
- Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
- " calling user. package=" + packageName + ", user=" + userId);
- result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
- } else {
- result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
- }
-
- if (callback != null) {
- mHandler.post(() -> {
- try {
- callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
- }
- });
- }
- }
-
- /**
- * Ask the package manager to perform a dex-opt with the given compiler filter.
- *
- * Note: exposed only for the shell command to allow moving packages explicitly to a
- * definite state.
- */
- @Override
- public boolean performDexOptMode(String packageName,
- boolean checkProfiles, String targetCompilerFilter, boolean force,
- boolean bootComplete, String splitName) {
- return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter,
- force, bootComplete, splitName);
- }
-
- /**
- * Ask the package manager to perform a dex-opt with the given compiler filter on the
- * secondary dex files belonging to the given package.
- *
- * Note: exposed only for the shell command to allow moving packages explicitly to a
- * definite state.
- */
- @Override
- public boolean performDexOptSecondary(String packageName, String compilerFilter,
- boolean force) {
- return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force);
- }
-
- /**
- * Reconcile the information we have about the secondary dex files belonging to
- * {@code packageName} and the actual dex files. For all dex files that were
- * deleted, update the internal records and delete the generated oat files.
- */
- @Override
- public void reconcileSecondaryDexFiles(String packageName) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return;
- } else if (isInstantAppInternal(
- packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) {
- return;
- }
- mDexManager.reconcileSecondaryDexFiles(packageName);
- }
-
/*package*/ DexManager getDexManager() {
return mDexManager;
}
@@ -3872,67 +3059,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public void dumpProfiles(String packageName) {
- /* Only the shell, root, or the app user should be able to dump profiles. */
- final int callingUid = Binder.getCallingUid();
- final String[] callerPackageNames = getPackagesForUid(callingUid);
- if (callingUid != Process.SHELL_UID
- && callingUid != Process.ROOT_UID
- && !ArrayUtils.contains(callerPackageNames, packageName)) {
- throw new SecurityException("dumpProfiles");
- }
-
- AndroidPackage pkg = getPackage(packageName);
- if (pkg == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
-
- synchronized (mInstallLock) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
- mArtManagerService.dumpProfiles(pkg);
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- @Override
- public void forceDexOpt(String packageName) {
- mDexOptHelper.forceDexOpt(packageName);
- }
-
int[] resolveUserIds(int userId) {
return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
}
- @Override
- public Property getProperty(String propertyName, String packageName, String className) {
- Objects.requireNonNull(propertyName);
- Objects.requireNonNull(packageName);
- PackageStateInternal packageState = mComputer.getPackageStateFiltered(packageName,
- Binder.getCallingUid(), UserHandle.getCallingUserId());
- if (packageState == null) {
- return null;
- }
- return mPackageProperty.getProperty(propertyName, packageName, className);
- }
-
- @Override
- public ParceledListSlice<Property> queryProperty(
- String propertyName, @PropertyLocation int componentType) {
- Objects.requireNonNull(propertyName);
- final int callingUid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getCallingUserId();
- final List<Property> result =
- mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
- final PackageStateInternal ps = getPackageStateInternal(packageName);
- return shouldFilterApplication(ps, callingUid, callingUserId);
- });
- if (result == null) {
- return ParceledListSlice.emptyList();
- }
- return new ParceledListSlice<>(result);
- }
-
private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
if (installerActivity == null) {
if (DEBUG_INSTANT) {
@@ -4052,159 +3182,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
- int userId) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
- final int callingUid = Binder.getCallingUid();
- enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
- true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
-
- if (hidden && isPackageDeviceAdmin(packageName, userId)) {
- Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
- return false;
- }
-
- // Do not allow "android" is being disabled
- if ("android".equals(packageName)) {
- Slog.w(TAG, "Cannot hide package: android");
- return false;
- }
-
- final long callingId = Binder.clearCallingIdentity();
- try {
- final PackageStateInternal packageState =
- mComputer.getPackageStateFiltered(packageName, callingUid, userId);
- if (packageState == null) {
- return false;
- }
-
- // Cannot hide static shared libs as they are considered
- // a part of the using app (emulating static linking). Also
- // static libs are installed always on internal storage.
- AndroidPackage pkg = packageState.getPkg();
- if (pkg != null) {
- // Cannot hide SDK libs as they are controlled by SDK manager.
- if (pkg.getSdkLibName() != null) {
- Slog.w(TAG, "Cannot hide package: " + packageName
- + " providing SDK library: "
- + pkg.getSdkLibName());
- return false;
- }
- // Cannot hide static shared libs as they are considered
- // a part of the using app (emulating static linking). Also
- // static libs are installed always on internal storage.
- if (pkg.getStaticSharedLibName() != null) {
- Slog.w(TAG, "Cannot hide package: " + packageName
- + " providing static shared library: "
- + pkg.getStaticSharedLibName());
- return false;
- }
- }
- // Only allow protected packages to hide themselves.
- if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId())
- && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
- Slog.w(TAG, "Not hiding protected package: " + packageName);
- return false;
- }
-
- if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) {
- return false;
- }
-
- commitPackageStateMutation(null, packageName, packageState1 ->
- packageState1.userState(userId).setHidden(hidden));
-
- final PackageStateInternal newPackageState = getPackageStateInternal(packageName);
-
- if (hidden) {
- killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg");
- sendApplicationHiddenForUser(packageName, newPackageState, userId);
- } else {
- sendPackageAddedForUser(packageName, newPackageState, userId, DataLoaderType.NONE);
- }
-
- scheduleWritePackageRestrictions(userId);
- return true;
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
- @Override
- public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
- final int callingUid = Binder.getCallingUid();
- final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
- || callingUid == Process.SYSTEM_UID;
- if (!calledFromSystemOrPhone) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
- "setSystemAppHiddenUntilInstalled");
- }
-
- final PackageStateInternal stateRead = getPackageStateInternal(packageName);
- if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) {
- return;
- }
- if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
- throw new SecurityException("Only system or phone callers can modify core apps");
- }
-
- commitPackageStateMutation(null, mutator -> {
- mutator.forPackage(packageName)
- .setHiddenUntilInstalled(hidden);
- mutator.forDisabledSystemPackage(packageName)
- .setHiddenUntilInstalled(hidden);
- });
- }
-
- @Override
- public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
- final int callingUid = Binder.getCallingUid();
- final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
- || callingUid == Process.SYSTEM_UID;
- if (!calledFromSystemOrPhone) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
- "setSystemAppHiddenUntilInstalled");
- }
-
- final PackageStateInternal packageState = getPackageStateInternal(packageName);
- // The target app should always be in system
- if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) {
- return false;
- }
- if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
- throw new SecurityException("Only system or phone callers can modify core apps");
- }
- // Check if the install state is the same
- if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) {
- return false;
- }
-
- final long callingId = Binder.clearCallingIdentity();
- try {
- if (installed) {
- // install the app from uninstalled state
- installExistingPackageAsUser(
- packageName,
- userId,
- PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
- PackageManager.INSTALL_REASON_DEVICE_SETUP,
- null);
- return true;
- }
-
- // uninstall the app from installed state
- deletePackageVersioned(
- new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
- new LegacyPackageDeleteObserver(null).getBinder(),
- userId,
- PackageManager.DELETE_SYSTEM_APP);
- return true;
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
private void sendApplicationHiddenForUser(String packageName, PackageStateInternal packageState,
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -4216,26 +3193,6 @@ public class PackageManagerService extends IPackageManager.Stub
info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/);
}
- /**
- * Returns true if application is not found or there was an error. Otherwise it returns
- * the hidden state of the package for the given user.
- */
- @Override
- public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
- @UserIdInt int userId) {
- return mComputer.getApplicationHiddenSettingAsUser(packageName, userId);
- }
-
- /**
- * @hide
- */
- @Override
- public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
- int installReason, List<String> whiteListedPermissions) {
- return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
- installReason, whiteListedPermissions, null);
- }
-
boolean isUserRestricted(int userId, String restrictionKey) {
Bundle restrictions = mUserManager.getUserRestrictions(userId);
if (restrictions.getBoolean(restrictionKey, false)) {
@@ -4245,77 +3202,6 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
- @Override
- public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
- int restrictionFlags, int userId) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
- "setDistractingPackageRestrictionsAsUser");
-
- final int callingUid = Binder.getCallingUid();
- if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
- && UserHandle.getUserId(callingUid) != userId) {
- throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
- + userId);
- }
- Objects.requireNonNull(packageNames, "packageNames cannot be null");
- if (restrictionFlags != 0
- && !mSuspendPackageHelper.isSuspendAllowedForUser(userId, callingUid)) {
- Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
- return packageNames;
- }
-
- final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
- final IntArray changedUids = new IntArray(packageNames.length);
- final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
-
- ArraySet<String> changesToCommit = new ArraySet<>();
- Computer computer = snapshotComputer();
- final boolean[] canRestrict = (restrictionFlags != 0)
- ? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId,
- callingUid) : null;
- for (int i = 0; i < packageNames.length; i++) {
- final String packageName = packageNames[i];
- final PackageStateInternal packageState =
- computer.getPackageStateInternal(packageName);
- if (packageState == null
- || computer.shouldFilterApplication(packageState, callingUid, userId)) {
- Slog.w(TAG, "Could not find package setting for package: " + packageName
- + ". Skipping...");
- unactionedPackages.add(packageName);
- continue;
- }
- if (canRestrict != null && !canRestrict[i]) {
- unactionedPackages.add(packageName);
- continue;
- }
- final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
- .getDistractionFlags();
- if (restrictionFlags != oldDistractionFlags) {
- changedPackagesList.add(packageName);
- changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
- changesToCommit.add(packageName);
- }
- }
-
- commitPackageStateMutation(null, mutator -> {
- final int size = changesToCommit.size();
- for (int index = 0; index < size; index++) {
- mutator.forPackage(changesToCommit.valueAt(index))
- .userState(userId)
- .setDistractionFlags(restrictionFlags);
- }
- });
-
- if (!changedPackagesList.isEmpty()) {
- final String[] changedPackages = changedPackagesList.toArray(
- new String[changedPackagesList.size()]);
- mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged(
- changedPackages, changedUids.toArray(), userId, restrictionFlags));
- scheduleWritePackageRestrictions(userId);
- }
- return unactionedPackages.toArray(new String[0]);
- }
-
private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
int userId, String callingMethod) {
if (callingUid == Process.ROOT_UID
@@ -4326,7 +3212,7 @@ public class PackageManagerService extends IPackageManager.Stub
final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
if (ownerPackage != null) {
- final int ownerUid = getPackageUid(ownerPackage, 0, userId);
+ final int ownerUid = mIPackageManager.getPackageUid(ownerPackage, 0, userId);
if (ownerUid == callingUid) {
return;
}
@@ -4335,7 +3221,7 @@ public class PackageManagerService extends IPackageManager.Stub
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
callingMethod);
- final int packageUid = getPackageUid(callingPackage, 0, userId);
+ final int packageUid = mIPackageManager.getPackageUid(callingPackage, 0, userId);
final boolean allowedPackageUid = packageUid == callingUid;
// TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
final boolean allowedShell = callingUid == SHELL_UID
@@ -4347,34 +3233,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
- PersistableBundle appExtras, PersistableBundle launcherExtras,
- SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
- final int callingUid = Binder.getCallingUid();
- enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
- "setPackagesSuspendedAsUser");
- return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames,
- suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId,
- callingUid);
- }
-
- @Override
- public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
- final int callingUid = Binder.getCallingUid();
- if (getPackageUid(packageName, 0, userId) != callingUid) {
- throw new SecurityException("Calling package " + packageName
- + " does not belong to calling uid " + callingUid);
- }
- return mSuspendPackageHelper.getSuspendedPackageAppExtras(
- packageName, userId, callingUid);
- }
-
- @Override
- public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
- return mComputer.isPackageSuspendedForUser(packageName, userId);
- }
-
void unsuspendForSuspendingPackage(@NonNull Computer computer, String suspendingPackage,
@UserIdInt int userId) {
// TODO: This can be replaced by a special parameter to iterate all packages, rather than
@@ -4429,67 +3287,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
- Objects.requireNonNull(packageNames, "packageNames cannot be null");
- mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
- "getUnsuspendablePackagesForUser");
- final int callingUid = Binder.getCallingUid();
- if (UserHandle.getUserId(callingUid) != userId) {
- throw new SecurityException("Calling uid " + callingUid
- + " cannot query getUnsuspendablePackagesForUser for user " + userId);
- }
- return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(),
- packageNames, userId, callingUid);
- }
-
- @Override
- public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
- "Only package verification agents can verify applications");
- final int callingUid = Binder.getCallingUid();
-
- final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
- final PackageVerificationResponse response = new PackageVerificationResponse(
- verificationCode, callingUid);
- msg.arg1 = id;
- msg.obj = response;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
- long millisecondsToDelay) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
- "Only package verification agents can extend verification timeouts");
- final int callingUid = Binder.getCallingUid();
-
- mHandler.post(() -> {
- final PackageVerificationState state = mPendingVerification.get(id);
- final PackageVerificationResponse response = new PackageVerificationResponse(
- verificationCodeAtTimeout, callingUid);
-
- long delay = millisecondsToDelay;
- if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
- delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
- }
- if (delay < 0) {
- delay = 0;
- }
-
- if ((state != null) && !state.timeoutExtended()) {
- state.extendTimeout();
-
- final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
- msg.arg1 = id;
- msg.obj = response;
- mHandler.sendMessageDelayed(msg, delay);
- }
- });
- }
-
private void setEnableRollbackCode(int token, int enableRollbackCode) {
final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
msg.arg1 = token;
@@ -4497,223 +3294,6 @@ public class PackageManagerService extends IPackageManager.Stub
mHandler.sendMessage(msg);
}
- @Override
- public void finishPackageInstall(int token, boolean didLaunch) {
- PackageManagerServiceUtils.enforceSystemOrRoot(
- "Only the system is allowed to finish installs");
-
- if (DEBUG_INSTALL) {
- Slog.v(TAG, "BM finishing package install for " + token);
- }
- Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
-
- final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
- mHandler.sendMessage(msg);
- }
-
- @Deprecated
- @Override
- public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
- DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
- id, verificationCode, failedDomains, Binder.getCallingUid());
- }
-
- @Deprecated
- @Override
- public int getIntentVerificationStatus(String packageName, int userId) {
- return mDomainVerificationManager.getLegacyState(packageName, userId);
- }
-
- @Deprecated
- @Override
- public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
- return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
- }
-
- @Deprecated
- @Override
- public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
- String packageName) {
- return ParceledListSlice.emptyList();
- }
-
- @NonNull
- @Override
- public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
- return mComputer.getAllIntentFilters(packageName);
- }
-
- @Override
- public void setInstallerPackageName(String targetPackage, String installerPackageName) {
- final int callingUid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(callingUid);
- final FunctionalUtils.ThrowingCheckedFunction<Computer, Boolean, RuntimeException>
- implementation = computer -> {
- if (computer.getInstantAppPackageName(callingUid) != null) {
- return false;
- }
-
- PackageStateInternal targetPackageState =
- computer.getPackageStateInternal(targetPackage);
- if (targetPackageState == null
- || computer.shouldFilterApplication(targetPackageState, callingUid,
- callingUserId)) {
- throw new IllegalArgumentException("Unknown target package: " + targetPackage);
- }
-
- PackageStateInternal installerPackageState = null;
- if (installerPackageName != null) {
- installerPackageState = computer.getPackageStateInternal(installerPackageName);
- if (installerPackageState == null
- || shouldFilterApplication(
- installerPackageState, callingUid, callingUserId)) {
- throw new IllegalArgumentException("Unknown installer package: "
- + installerPackageName);
- }
- }
-
- Signature[] callerSignature;
- final int appId = UserHandle.getAppId(callingUid);
- Pair<PackageStateInternal, SharedUserApi> either =
- computer.getPackageOrSharedUser(appId);
- if (either != null) {
- if (either.first != null) {
- callerSignature = either.first.getSigningDetails().getSignatures();
- } else {
- callerSignature = either.second.getSigningDetails().getSignatures();
- }
- } else {
- throw new SecurityException("Unknown calling UID: " + callingUid);
- }
-
- // Verify: can't set installerPackageName to a package that is
- // not signed with the same cert as the caller.
- if (installerPackageState != null) {
- if (compareSignatures(callerSignature,
- installerPackageState.getSigningDetails().getSignatures())
- != PackageManager.SIGNATURE_MATCH) {
- throw new SecurityException(
- "Caller does not have same cert as new installer package "
- + installerPackageName);
- }
- }
-
- // Verify: if target already has an installer package, it must
- // be signed with the same cert as the caller.
- String targetInstallerPackageName =
- targetPackageState.getInstallSource().installerPackageName;
- PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null
- ? null : computer.getPackageStateInternal(targetInstallerPackageName);
-
- if (targetInstallerPkgSetting != null) {
- if (compareSignatures(callerSignature,
- targetInstallerPkgSetting.getSigningDetails().getSignatures())
- != PackageManager.SIGNATURE_MATCH) {
- throw new SecurityException(
- "Caller does not have same cert as old installer package "
- + targetInstallerPackageName);
- }
- } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
- != PERMISSION_GRANTED) {
- // This is probably an attempt to exploit vulnerability b/150857253 of taking
- // privileged installer permissions when the installer has been uninstalled or
- // was never set.
- EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
-
- final long binderToken = Binder.clearCallingIdentity();
- try {
- if (mInjector.getCompatibility().isChangeEnabledByUid(
- THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
- callingUid)) {
- throw new SecurityException("Neither user " + callingUid
- + " nor current process has "
- + Manifest.permission.INSTALL_PACKAGES);
- } else {
- // If change disabled, fail silently for backwards compatibility
- return false;
- }
- } finally {
- Binder.restoreCallingIdentity(binderToken);
- }
- }
-
- return true;
- };
- PackageStateMutator.InitialState initialState = recordInitialState();
- boolean allowed = implementation.apply(snapshotComputer());
- if (allowed) {
- // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
- // should find an alternative which avoids any race conditions
- PackageStateInternal targetPackageState;
- synchronized (mLock) {
- PackageStateMutator.Result result = commitPackageStateMutation(initialState,
- targetPackage, state -> state.setInstaller(installerPackageName));
- if (result.isPackagesChanged() || result.isStateChanged()) {
- synchronized (mPackageStateWriteLock) {
- allowed = implementation.apply(snapshotComputer());
- if (allowed) {
- commitPackageStateMutation(null, targetPackage,
- state -> state.setInstaller(installerPackageName));
- } else {
- return;
- }
- }
- }
- targetPackageState = getPackageStateInternal(targetPackage);
- mSettings.addInstallerPackageNames(targetPackageState.getInstallSource());
- }
- mAppsFilter.addPackage(targetPackageState);
- scheduleWriteSettings();
- }
- }
-
- @Override
- public void setApplicationCategoryHint(String packageName, int categoryHint,
- String callerPackageName) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- throw new SecurityException("Instant applications don't have access to this method");
- }
- mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
- callerPackageName);
-
- final PackageStateMutator.InitialState initialState = recordInitialState();
-
- final FunctionalUtils.ThrowingFunction<Computer, PackageStateMutator.Result>
- implementation = computer -> {
- PackageStateInternal packageState = computer.getPackageStateFiltered(packageName,
- Binder.getCallingUid(), UserHandle.getCallingUserId());
- if (packageState == null) {
- throw new IllegalArgumentException("Unknown target package " + packageName);
- }
-
- if (!Objects.equals(callerPackageName,
- packageState.getInstallSource().installerPackageName)) {
- throw new IllegalArgumentException("Calling package " + callerPackageName
- + " is not installer for " + packageName);
- }
-
- if (packageState.getCategoryOverride() != categoryHint) {
- return commitPackageStateMutation(initialState,
- packageName, state -> state.setCategoryOverride(categoryHint));
- } else {
- return null;
- }
- };
-
- PackageStateMutator.Result result = implementation.apply(snapshotComputer());
- if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
- // TODO: Specific return value of what state changed?
- // The installer on record might have changed, retry with lock
- synchronized (mPackageStateWriteLock) {
- result = implementation.apply(snapshotComputer());
- }
- }
-
- if (result != null && result.isCommitted()) {
- scheduleWriteSettings();
- }
- }
-
/**
* Callback from PackageSettings whenever an app is first transitioned out of the
* 'stopped' state. Normally we just issue the broadcast, but we can't do that if
@@ -4792,21 +3372,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public void deletePackageAsUser(String packageName, int versionCode,
- IPackageDeleteObserver observer, int userId, int flags) {
- deletePackageVersioned(new VersionedPackage(packageName, versionCode),
- new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
- }
-
- @Override
public void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId) {
mDeletePackageHelper.deleteExistingPackageAsUser(
versionedPackage, observer, userId);
}
- @Override
public void deletePackageVersioned(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
mDeletePackageHelper.deletePackageVersionedInternal(
@@ -4823,15 +3394,14 @@ public class PackageManagerService extends IPackageManager.Stub
boolean isCallerVerifier(int callingUid) {
final int callingUserId = UserHandle.getUserId(callingUid);
- return mRequiredVerifierPackage != null &&
- callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
+ return mRequiredVerifierPackage != null && callingUid == mIPackageManager.getPackageUid(
+ mRequiredVerifierPackage, 0, callingUserId);
}
- @Override
public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
final int callingUid = Binder.getCallingUid();
- if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
- != PERMISSION_GRANTED) {
+ if (mIPackageManager.checkUidPermission(android.Manifest.permission.MANAGE_USERS,
+ callingUid) != PERMISSION_GRANTED) {
EventLog.writeEvent(0x534e4554, "128599183", -1, "");
throw new SecurityException(android.Manifest.permission.MANAGE_USERS
+ " permission is required to call this API");
@@ -4886,139 +3456,6 @@ public class PackageManagerService extends IPackageManager.Stub
return mDevicePolicyManager;
}
- @Override
- public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
- int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.DELETE_PACKAGES, null);
- PackageStateInternal packageState = getPackageStateInternal(packageName);
- if (packageState != null && packageState.getPkg() != null) {
- AndroidPackage pkg = packageState.getPkg();
- // Cannot block uninstall SDK libs as they are controlled by SDK manager.
- if (pkg.getSdkLibName() != null) {
- Slog.w(TAG, "Cannot block uninstall of package: " + packageName
- + " providing SDK library: " + pkg.getSdkLibName());
- return false;
- }
- // Cannot block uninstall of static shared libs as they are
- // considered a part of the using app (emulating static linking).
- // Also static libs are installed always on internal storage.
- if (pkg.getStaticSharedLibName() != null) {
- Slog.w(TAG, "Cannot block uninstall of package: " + packageName
- + " providing static shared library: " + pkg.getStaticSharedLibName());
- return false;
- }
- }
- synchronized (mLock) {
- mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
- }
-
- scheduleWritePackageRestrictions(userId);
- return true;
- }
-
- @Override
- public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
- return mComputer.getBlockUninstallForUser(packageName, userId);
- }
-
- @Override
- public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) {
- PackageManagerServiceUtils.enforceSystemOrRoot(
- "setRequiredForSystemUser can only be run by the system or root");
-
- PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
- packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser));
- if (!result.isCommitted()) {
- return false;
- }
-
- scheduleWriteSettings();
- return true;
- }
-
- @Override
- public void clearApplicationProfileData(String packageName) {
- PackageManagerServiceUtils.enforceSystemOrRoot(
- "Only the system can clear all profile data");
-
- final AndroidPackage pkg = getPackage(packageName);
- try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) {
- synchronized (mInstallLock) {
- mAppDataHelper.clearAppProfilesLIF(pkg);
- }
- }
- }
-
- @Override
- public void clearApplicationUserData(final String packageName,
- final IPackageDataObserver observer, final int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_USER_DATA, null);
-
- final int callingUid = Binder.getCallingUid();
- enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
- false /* checkShell */, "clear application data");
-
- if (mComputer.getPackageStateFiltered(packageName, callingUid, userId) == null) {
- if (observer != null) {
- mHandler.post(() -> {
- try {
- observer.onRemoveCompleted(packageName, false);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
- }
- });
- }
- return;
- }
- if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
- throw new SecurityException("Cannot clear data for a protected package: "
- + packageName);
- }
-
- // Queue up an async operation since the package deletion may take a little while.
- mHandler.post(new Runnable() {
- public void run() {
- mHandler.removeCallbacks(this);
- final boolean succeeded;
- try (PackageFreezer freezer = freezePackage(packageName,
- "clearApplicationUserData")) {
- synchronized (mInstallLock) {
- succeeded = clearApplicationUserDataLIF(packageName, userId);
- }
- mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId);
- synchronized (mLock) {
- if (succeeded) {
- resetComponentEnabledSettingsIfNeededLPw(packageName, userId);
- }
- }
- }
- if (succeeded) {
- // invoke DeviceStorageMonitor's update method to clear any notifications
- DeviceStorageMonitorInternal dsm = LocalServices
- .getService(DeviceStorageMonitorInternal.class);
- if (dsm != null) {
- dsm.checkMemory();
- }
- if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
- == PERMISSION_GRANTED) {
- unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId);
- removeAllDistractingPackageRestrictions(userId);
- flushPackageRestrictionsAsUserInternalLocked(userId);
- }
- }
- if (observer != null) {
- try {
- observer.onRemoveCompleted(packageName, succeeded);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
- }
- } //end if observer
- } //end run
- });
- }
-
private boolean clearApplicationUserDataLIF(String packageName, int userId) {
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
@@ -5101,106 +3538,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public void deleteApplicationCacheFiles(final String packageName,
- final IPackageDataObserver observer) {
- final int userId = UserHandle.getCallingUserId();
- deleteApplicationCacheFilesAsUser(packageName, userId, observer);
- }
-
- @Override
- public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
- final IPackageDataObserver observer) {
- final int callingUid = Binder.getCallingUid();
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
- != PackageManager.PERMISSION_GRANTED) {
- // If the caller has the old delete cache permission, silently ignore. Else throw.
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DELETE_CACHE_FILES)
- == PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
- android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
- ", silently ignoring");
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
- }
- enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
- /* checkShell= */ false, "delete application cache files");
- final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_INSTANT_APPS);
-
- final AndroidPackage pkg = getPackage(packageName);
-
- // Queue up an async operation since the package deletion may take a little while.
- mHandler.post(() -> {
- final PackageStateInternal ps =
- pkg == null ? null : getPackageStateInternal(pkg.getPackageName());
- boolean doClearData = true;
- if (ps != null) {
- final boolean targetIsInstantApp =
- ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp();
- doClearData = !targetIsInstantApp
- || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
- }
- if (doClearData) {
- synchronized (mInstallLock) {
- final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
- // We're only clearing cache files, so we don't care if the
- // app is unfrozen and still able to run
- mAppDataHelper.clearAppDataLIF(pkg, userId,
- flags | Installer.FLAG_CLEAR_CACHE_ONLY);
- mAppDataHelper.clearAppDataLIF(pkg, userId,
- flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
- }
- }
- if (observer != null) {
- try {
- observer.onRemoveCompleted(packageName, true);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
- }
- }
- });
- }
-
- @Override
- public void getPackageSizeInfo(final String packageName, int userId,
- final IPackageStatsObserver observer) {
- throw new UnsupportedOperationException(
- "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
- }
-
int getUidTargetSdkVersion(int uid) {
return mComputer.getUidTargetSdkVersion(uid);
}
- @Override
- public void addPreferredActivity(IntentFilter filter, int match,
- ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
- mPreferredActivityHelper.addPreferredActivity(
- new WatchedIntentFilter(filter), match, set, activity, true, userId,
- "Adding preferred", removeExisting);
- }
-
void postPreferredActivityChangedBroadcast(int userId) {
mHandler.post(() -> mBroadcastHelper.sendPreferredActivityChangedBroadcast(userId));
}
- @Override
- public void replacePreferredActivity(IntentFilter filter, int match,
- ComponentName[] set, ComponentName activity, int userId) {
- mPreferredActivityHelper.replacePreferredActivity(new WatchedIntentFilter(filter), match,
- set, activity, userId);
- }
-
- @Override
- public void clearPackagePreferredActivities(String packageName) {
- mPreferredActivityHelper.clearPackagePreferredActivities(packageName);
- }
-
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@GuardedBy("mLock")
@@ -5220,109 +3565,6 @@ public class PackageManagerService extends IPackageManager.Stub
mPreferredActivityHelper.updateDefaultHomeNotLocked(userId);
}
- @Override
- public void resetApplicationPreferences(int userId) {
- mPreferredActivityHelper.resetApplicationPreferences(userId);
- }
-
- @Override
- public int getPreferredActivities(List<IntentFilter> outFilters,
- List<ComponentName> outActivities, String packageName) {
- return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities,
- packageName, mComputer);
- }
-
- @Override
- public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
- int userId) {
- mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter),
- activity, userId);
- }
-
- @Override
- public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
- mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId);
- }
-
- /**
- * Non-Binder method, support for the backup/restore mechanism: write the
- * full set of preferred activities in its canonical XML format. Returns the
- * XML output as a byte array, or null if there is none.
- */
- @Override
- public byte[] getPreferredActivityBackup(int userId) {
- return mPreferredActivityHelper.getPreferredActivityBackup(userId);
- }
-
- @Override
- public void restorePreferredActivities(byte[] backup, int userId) {
- mPreferredActivityHelper.restorePreferredActivities(backup, userId);
- }
-
- /**
- * Non-Binder method, support for the backup/restore mechanism: write the
- * default browser (etc) settings in its canonical XML format. Returns the default
- * browser XML representation as a byte array, or null if there is none.
- */
- @Override
- public byte[] getDefaultAppsBackup(int userId) {
- return mPreferredActivityHelper.getDefaultAppsBackup(userId);
- }
-
- @Override
- public void restoreDefaultApps(byte[] backup, int userId) {
- mPreferredActivityHelper.restoreDefaultApps(backup, userId);
- }
-
- @Override
- public byte[] getDomainVerificationBackup(int userId) {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Only the system may call getDomainVerificationBackup()");
- }
-
- try {
- try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
- TypedXmlSerializer serializer = Xml.resolveSerializer(output);
- mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true,
- userId);
- return output.toByteArray();
- }
- } catch (Exception e) {
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Unable to write domain verification for backup", e);
- }
- return null;
- }
- }
-
- @Override
- public void restoreDomainVerification(byte[] backup, int userId) {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Only the system may call restorePreferredActivities()");
- }
-
- try {
- ByteArrayInputStream input = new ByteArrayInputStream(backup);
- TypedXmlPullParser parser = Xml.resolvePullParser(input);
-
- // User ID input isn't necessary here as it assumes the user integers match and that
- // the only states inside the backup XML are for the target user.
- mDomainVerificationManager.restoreSettings(snapshotComputer(), parser);
- input.close();
- } catch (Exception e) {
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage());
- }
- }
- }
-
- @Override
- public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
- int sourceUserId, int targetUserId, int flags) {
- addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage,
- sourceUserId, targetUserId, flags);
- }
-
/**
* Variant that takes a {@link WatchedIntentFilter}
*/
@@ -5358,55 +3600,25 @@ public class PackageManagerService extends IPackageManager.Stub
scheduleWritePackageRestrictions(sourceUserId);
}
- @Override
- public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- final int callingUid = Binder.getCallingUid();
- enforceOwnerRights(ownerPackage, callingUid);
- PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
- UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
- synchronized (mLock) {
- CrossProfileIntentResolver resolver =
- mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
- ArraySet<CrossProfileIntentFilter> set =
- new ArraySet<>(resolver.filterSet());
- for (CrossProfileIntentFilter filter : set) {
- if (filter.getOwnerPackage().equals(ownerPackage)) {
- resolver.removeFilter(filter);
- }
- }
- }
- scheduleWritePackageRestrictions(sourceUserId);
- }
-
// Enforcing that callingUid is owning pkg on userId
private void enforceOwnerRights(String pkg, int callingUid) {
// The system owns everything.
if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
return;
}
- final String[] callerPackageNames = getPackagesForUid(callingUid);
+ final String[] callerPackageNames = mIPackageManager.getPackagesForUid(callingUid);
if (!ArrayUtils.contains(callerPackageNames, pkg)) {
throw new SecurityException("Calling uid " + callingUid
+ " does not own package " + pkg);
}
final int callingUserId = UserHandle.getUserId(callingUid);
- PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
+ PackageInfo pi = mIPackageManager.getPackageInfo(pkg, 0, callingUserId);
if (pi == null) {
throw new IllegalArgumentException("Unknown package " + pkg + " on user "
+ callingUserId);
}
}
- @Override
- public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return null;
- }
- return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
- }
-
public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
UserManagerService ums = UserManagerService.getInstance();
if (ums == null || sessionInfo.isStaged()) {
@@ -5437,11 +3649,6 @@ public class PackageManagerService extends IPackageManager.Stub
userId);
}
- @Override
- public void setHomeActivity(ComponentName comp, int userId) {
- mPreferredActivityHelper.setHomeActivity(comp, userId);
- }
-
private @Nullable String getSetupWizardPackageNameImpl(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
@@ -5493,84 +3700,17 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public String getDefaultTextClassifierPackageName() {
- return ensureSystemPackageName(
- mContext.getString(R.string.config_servicesExtensionPackage));
- }
-
- @Override
- public String getSystemTextClassifierPackageName() {
- return ensureSystemPackageName(
- mContext.getString(R.string.config_defaultTextClassifierPackage));
- }
-
- @Override
- public @Nullable String getAttentionServicePackageName() {
- return ensureSystemPackageName(
- getPackageFromComponentString(R.string.config_defaultAttentionService));
- }
-
- @Override
- public @Nullable String getRotationResolverPackageName() {
- return ensureSystemPackageName(
- getPackageFromComponentString(R.string.config_defaultRotationResolverService));
- }
-
@Nullable
private String getDeviceConfiguratorPackageName() {
return ensureSystemPackageName(mContext.getString(
R.string.config_deviceConfiguratorPackageName));
}
- @Override
- public String getWellbeingPackageName() {
- final long identity = Binder.clearCallingIdentity();
- try {
- return CollectionUtils.firstOrNull(
- mContext.getSystemService(RoleManager.class).getRoleHolders(
- RoleManager.ROLE_SYSTEM_WELLBEING));
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public String getAppPredictionServicePackageName() {
- return ensureSystemPackageName(
- getPackageFromComponentString(R.string.config_defaultAppPredictionService));
- }
-
- @Override
- public String getSystemCaptionsServicePackageName() {
- return ensureSystemPackageName(
- getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
- }
-
- @Override
- public String getSetupWizardPackageName() {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Non-system caller");
- }
- return mPmInternal.getSetupWizardPackageName();
- }
-
public @Nullable String getAmbientContextDetectionPackageName() {
return ensureSystemPackageName(getPackageFromComponentString(
R.string.config_defaultAmbientContextDetectionService));
}
- public String getIncidentReportApproverPackageName() {
- return ensureSystemPackageName(mContext.getString(
- R.string.config_incidentReportApproverPackage));
- }
-
- @Override
- public String getContentCaptureServicePackageName() {
- return ensureSystemPackageName(
- getPackageFromComponentString(R.string.config_defaultContentCaptureService));
- }
-
public String getOverlayConfigSignaturePackageName() {
return ensureSystemPackageName(mInjector.getSystemConfig()
.getOverlayConfigSignaturePackage());
@@ -5638,8 +3778,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
final long token = Binder.clearCallingIdentity();
try {
- if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
- PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
+ if (mIPackageManager.getPackageInfo(packageName, MATCH_FACTORY_ONLY,
+ UserHandle.USER_SYSTEM) == null) {
+ PackageInfo packageInfo =
+ mIPackageManager.getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
if (packageInfo != null) {
EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
"");
@@ -5652,39 +3794,6 @@ public class PackageManagerService extends IPackageManager.Stub
return packageName;
}
- @Override
- public void setApplicationEnabledSetting(String appPackageName,
- int newState, int flags, int userId, String callingPackage) {
- if (!mUserManager.exists(userId)) return;
- if (callingPackage == null) {
- callingPackage = Integer.toString(Binder.getCallingUid());
- }
-
- setEnabledSettings(List.of(new ComponentEnabledSetting(appPackageName, newState, flags)),
- userId, callingPackage);
- }
-
- @Override
- public void setUpdateAvailable(String packageName, boolean updateAvailable) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
- commitPackageStateMutation(null, packageName, state ->
- state.setUpdateAvailable(updateAvailable));
- }
-
- @Override
- public void overrideLabelAndIcon(@NonNull ComponentName componentName,
- @NonNull String nonLocalizedLabel, int icon, int userId) {
- if (TextUtils.isEmpty(nonLocalizedLabel)) {
- throw new IllegalArgumentException("Override label should be a valid String");
- }
- updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
- }
-
- @Override
- public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
- updateComponentLabelIcon(componentName, null, null, userId);
- }
-
@VisibleForTesting(visibility = Visibility.PRIVATE)
public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName,
@Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) {
@@ -5751,25 +3860,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public void setComponentEnabledSetting(ComponentName componentName,
- int newState, int flags, int userId) {
- if (!mUserManager.exists(userId)) return;
-
- setEnabledSettings(List.of(new ComponentEnabledSetting(componentName, newState, flags)),
- userId, null /* callingPackage */);
- }
-
- @Override
- public void setComponentEnabledSettings(List<ComponentEnabledSetting> settings, int userId) {
- if (!mUserManager.exists(userId)) return;
- if (settings == null || settings.isEmpty()) {
- throw new IllegalArgumentException("The list of enabled settings is empty");
- }
-
- setEnabledSettings(settings, userId, null /* callingPackage */);
- }
-
private void setEnabledSettings(List<ComponentEnabledSetting> settings, int userId,
String callingPackage) {
final int callingUid = Binder.getCallingUid();
@@ -5839,7 +3929,7 @@ public class PackageManagerService extends IPackageManager.Stub
continue;
}
final boolean isCallerTargetApp = ArrayUtils.contains(
- getPackagesForUid(callingUid), packageName);
+ mIPackageManager.getPackagesForUid(callingUid), packageName);
final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
// Limit who can change which apps
if (!isCallerTargetApp) {
@@ -6047,8 +4137,8 @@ public class PackageManagerService extends IPackageManager.Stub
pkgSetting.setEnabled(newState, userId, callingPackage);
if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
|| newState == COMPONENT_ENABLED_STATE_DISABLED)
- && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
- == PERMISSION_GRANTED) {
+ && mIPackageManager.checkPermission(Manifest.permission.SUSPEND_APPS,
+ packageName, userId) == PERMISSION_GRANTED) {
// This app should not generally be allowed to get disabled by the UI, but
// if it ever does, we don't want to end up with some of the user's apps
// permanently suspended.
@@ -6091,22 +4181,6 @@ public class PackageManagerService extends IPackageManager.Stub
return true;
}
- @WorkerThread
- @Override
- public void flushPackageRestrictionsAsUser(int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return;
- }
- if (!mUserManager.exists(userId)) {
- return;
- }
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
- false /* checkShell */, "flushPackageRestrictions");
- synchronized (mLock) {
- flushPackageRestrictionsAsUserInternalLocked(userId);
- }
- }
-
@GuardedBy("mLock")
private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
// NOTE: this invokes synchronous disk access, so callers using this
@@ -6139,100 +4213,17 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.getBroadcastAllowList(packageName, userIds, isInstantApp);
}
- @Override
- public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
- if (!mUserManager.exists(userId)) return;
- final int callingUid = Binder.getCallingUid();
- final Computer computer = snapshotComputer();
- if (computer.getInstantAppPackageName(callingUid) == null) {
- final int permission = mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
- final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
- if (!allowedByPermission
- && !ArrayUtils.contains(computer.getPackagesForUid(callingUid), packageName)) {
- throw new SecurityException(
- "Permission Denial: attempt to change stopped state from pid="
- + Binder.getCallingPid()
- + ", uid=" + callingUid + ", package=" + packageName);
- }
- computer.enforceCrossUserPermission(callingUid, userId,
- true /* requireFullPermission */, true /* checkShell */, "stop package");
-
- final PackageStateInternal packageState = computer.getPackageStateInternal(packageName);
- final PackageUserState packageUserState = packageState == null
- ? null : packageState.getUserStateOrDefault(userId);
- if (packageState != null
- && !computer.shouldFilterApplication(packageState, callingUid, userId)
- && packageUserState.isStopped() != stopped) {
- boolean wasNotLaunched = packageUserState.isNotLaunched();
- commitPackageStateMutation(null, packageName, state -> {
- PackageUserStateWrite userState = state.userState(userId);
- userState.setStopped(stopped);
- if (wasNotLaunched) {
- userState.setNotLaunched(false);
- }
- });
-
- if (wasNotLaunched) {
- final String installerPackageName =
- packageState.getInstallSource().installerPackageName;
- if (installerPackageName != null) {
- notifyFirstLaunch(packageName, installerPackageName, userId);
- }
- }
-
- scheduleWritePackageRestrictions(userId);
- }
- }
-
- // If this would cause the app to leave force-stop, then also make sure to unhibernate the
- // app if needed.
- if (!stopped) {
- mHandler.post(() -> {
- AppHibernationManagerInternal ah =
- mInjector.getLocalService(AppHibernationManagerInternal.class);
- if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
- ah.setHibernatingForUser(packageName, userId, false);
- ah.setHibernatingGlobally(packageName, false);
- }
- });
- }
- }
-
- @Nullable
- @Override
- public String getInstallerPackageName(@NonNull String packageName) {
- return mComputer.getInstallerPackageName(packageName);
- }
-
- @Override
- @Nullable
- public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
- return mComputer.getInstallSourceInfo(packageName);
- }
-
- @PackageManager.EnabledState
- @Override
- public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
- return mComputer.getApplicationEnabledSetting(packageName, userId);
- }
-
- @Override
- public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
- return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
- }
-
- @Override
- public void enterSafeMode() {
- PackageManagerServiceUtils.enforceSystemOrRoot(
- "Only the system can request entering safe mode");
-
- if (!mSystemReady) {
- mSafeMode = true;
+ /**
+ * Used by SystemServer
+ */
+ public void waitForAppDataPrepared() {
+ if (mPrepareAppDataFuture == null) {
+ return;
}
+ ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
+ mPrepareAppDataFuture = null;
}
- @Override
public void systemReady() {
PackageManagerServiceUtils.enforceSystemOrRoot(
"Only the system can claim the system is ready");
@@ -6263,7 +4254,7 @@ public class PackageManagerService extends IPackageManager.Stub
.getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
false, co, UserHandle.USER_ALL);
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
- .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
+ .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
co.onChange(true);
mAppsFilter.onSystemReady();
@@ -6395,44 +4386,11 @@ public class PackageManagerService extends IPackageManager.Stub
// Prune unused static shared libraries which have been cached a period of time
schedulePruneUnusedStaticSharedLibraries(false /* delay */);
- }
- /**
- * Used by SystemServer
- */
- public void waitForAppDataPrepared() {
- if (mPrepareAppDataFuture == null) {
- return;
+ // TODO(b/222706900): Remove this intent interceptor before T launch
+ if (mIntentResolverInterceptor != null) {
+ mIntentResolverInterceptor.registerListeners();
}
- ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
- mPrepareAppDataFuture = null;
- }
-
- @Override
- public boolean isSafeMode() {
- // allow instant applications
- return mSafeMode;
- }
-
- @Override
- public boolean hasSystemUidErrors() {
- // allow instant applications
- return false;
- }
-
- @Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out,
- FileDescriptor err, String[] args, ShellCallback callback,
- ResultReceiver resultReceiver) {
- (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell()))
- .exec(this, in, out, err, args, callback, resultReceiver);
- }
-
- @SuppressWarnings("resource")
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
- new DumpHelper(this).doDump(fd, pw, args);
}
void dumpSnapshotStats(PrintWriter pw, boolean isBrief) {
@@ -6471,9 +4429,9 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
for (String packageName : apkList) {
- setSystemAppHiddenUntilInstalled(packageName, true);
+ mIPackageManager.setSystemAppHiddenUntilInstalled(packageName, true);
for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
- setSystemAppInstallState(packageName, false, user.id);
+ mIPackageManager.setSystemAppInstallState(packageName, false, user.id);
}
}
}
@@ -6511,98 +4469,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public int movePackage(final String packageName, final String volumeUuid) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
-
- final int callingUid = Binder.getCallingUid();
- final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
- final int moveId = mNextMoveId.getAndIncrement();
- mHandler.post(() -> {
- try {
- MovePackageHelper movePackageHelper = new MovePackageHelper(this);
- movePackageHelper.movePackageInternal(
- packageName, volumeUuid, moveId, callingUid, user);
- } catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to move " + packageName, e);
- mMoveCallbacks.notifyStatusChanged(moveId, e.error);
- }
- });
- return moveId;
- }
-
- @Override
- public int movePrimaryStorage(String volumeUuid) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
-
- final int realMoveId = mNextMoveId.getAndIncrement();
- final Bundle extras = new Bundle();
- extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
- mMoveCallbacks.notifyCreated(realMoveId, extras);
-
- final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
- @Override
- public void onCreated(int moveId, Bundle extras) {
- // Ignored
- }
-
- @Override
- public void onStatusChanged(int moveId, int status, long estMillis) {
- mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
- }
- };
-
- final StorageManager storage = mInjector.getSystemService(StorageManager.class);
- storage.setPrimaryStorageUuid(volumeUuid, callback);
- return realMoveId;
- }
-
- @Override
- public int getMoveStatus(int moveId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
- return mMoveCallbacks.mLastStatus.get(moveId);
- }
-
- @Override
- public void registerMoveCallback(IPackageMoveObserver callback) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
- mMoveCallbacks.register(callback);
- }
-
- @Override
- public void unregisterMoveCallback(IPackageMoveObserver callback) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
- mMoveCallbacks.unregister(callback);
- }
-
- @Override
- public boolean setInstallLocation(int loc) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
- null);
- if (getInstallLocation() == loc) {
- return true;
- }
- if (loc == InstallLocationUtils.APP_INSTALL_AUTO
- || loc == InstallLocationUtils.APP_INSTALL_INTERNAL
- || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) {
- android.provider.Settings.Global.putInt(mContext.getContentResolver(),
- android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
- return true;
- }
- return false;
- }
-
- @Override
- public int getInstallLocation() {
- // allow instant app access
- return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
- android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
- InstallLocationUtils.APP_INSTALL_AUTO);
- }
-
/** Called by UserManagerService */
void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
synchronized (mLock) {
@@ -6662,18 +4528,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
- "Only package verification agents can read the verifier device identity");
-
- synchronized (mLock) {
- return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
- }
- }
-
- @Override
public boolean isStorageLow() {
// allow instant applications
final long token = Binder.clearCallingIdentity();
@@ -6690,50 +4544,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public IPackageInstaller getPackageInstaller() {
- // Return installer service for internal calls.
- if (PackageManagerServiceUtils.isSystemOrRoot()) {
- return mInstallerService;
- }
- // Return null for InstantApps.
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return null;
- }
- return mInstallerService;
- }
-
- @Override
- public IArtManager getArtManager() {
- return mArtManagerService;
- }
-
boolean userNeedsBadging(int userId) {
return mUserNeedsBadging.get(userId);
}
- @Nullable
- @Override
- public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
- return mComputer.getKeySetByAlias(packageName, alias);
- }
-
- @Nullable
- @Override
- public KeySet getSigningKeySet(@NonNull String packageName) {
- return mComputer.getSigningKeySet(packageName);
- }
-
- @Override
- public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
- return mComputer.isPackageSignedByKeySet(packageName, ks);
- }
-
- @Override
- public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) {
- return mComputer.isPackageSignedByKeySetExactly(packageName, ks);
- }
-
private void deletePackageIfUnused(final String packageName) {
PackageStateInternal ps = getPackageStateInternal(packageName);
if (ps == null) {
@@ -6790,6 +4604,2515 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.canQueryPackage(callingUid, targetPackageName);
}
+ void checkPackageStartable(@NonNull Computer snapshot, @NonNull String packageName,
+ @UserIdInt int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (snapshot.getInstantAppPackageName(callingUid) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
+ if (!mUserManager.exists(userId)) {
+ throw new SecurityException("User doesn't exist");
+ }
+ snapshot.enforceCrossUserPermission(callingUid, userId, false, false,
+ "checkPackageStartable");
+ switch (snapshot.getPackageStartability(mSafeMode, packageName, callingUid, userId)) {
+ case PACKAGE_STARTABILITY_NOT_FOUND:
+ throw new SecurityException("Package " + packageName + " was not found!");
+ case PACKAGE_STARTABILITY_NOT_SYSTEM:
+ throw new SecurityException("Package " + packageName + " not a system app!");
+ case PACKAGE_STARTABILITY_FROZEN:
+ throw new SecurityException("Package " + packageName + " is currently frozen!");
+ case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
+ throw new SecurityException("Package " + packageName + " is not encryption aware!");
+ case PACKAGE_STARTABILITY_OK:
+ default:
+ }
+ }
+
+ void setPackageStoppedState(@NonNull Computer snapshot, @NonNull String packageName,
+ boolean stopped, @UserIdInt int userId) {
+ if (!mUserManager.exists(userId)) return;
+ final int callingUid = Binder.getCallingUid();
+ if (snapshot.getInstantAppPackageName(callingUid) == null) {
+ final int permission = mContext.checkCallingOrSelfPermission(
+ Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
+ final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+ if (!allowedByPermission
+ && !ArrayUtils.contains(snapshot.getPackagesForUid(callingUid), packageName)) {
+ throw new SecurityException(
+ "Permission Denial: attempt to change stopped state from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + callingUid + ", package=" + packageName);
+ }
+ snapshot.enforceCrossUserPermission(callingUid, userId,
+ true /* requireFullPermission */, true /* checkShell */, "stop package");
+
+ final PackageStateInternal packageState =
+ snapshot.getPackageStateInternal(packageName);
+ final PackageUserState packageUserState = packageState == null
+ ? null : packageState.getUserStateOrDefault(userId);
+ if (packageState != null
+ && !snapshot.shouldFilterApplication(packageState, callingUid, userId)
+ && packageUserState.isStopped() != stopped) {
+ boolean wasNotLaunched = packageUserState.isNotLaunched();
+ commitPackageStateMutation(null, packageName, state -> {
+ PackageUserStateWrite userState = state.userState(userId);
+ userState.setStopped(stopped);
+ if (wasNotLaunched) {
+ userState.setNotLaunched(false);
+ }
+ });
+
+ if (wasNotLaunched) {
+ final String installerPackageName =
+ packageState.getInstallSource().installerPackageName;
+ if (installerPackageName != null) {
+ notifyFirstLaunch(packageName, installerPackageName, userId);
+ }
+ }
+
+ scheduleWritePackageRestrictions(userId);
+ }
+ }
+
+ // If this would cause the app to leave force-stop, then also make sure to unhibernate the
+ // app if needed.
+ if (!stopped) {
+ mHandler.post(() -> {
+ AppHibernationManagerInternal ah =
+ mInjector.getLocalService(AppHibernationManagerInternal.class);
+ if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
+ ah.setHibernatingForUser(packageName, userId, false);
+ ah.setHibernatingGlobally(packageName, false);
+ }
+ });
+ }
+ }
+
+ public class IPackageManagerImpl extends IPackageManager.Stub {
+
+ @Override
+ public boolean activitySupportsIntent(ComponentName component, Intent intent,
+ String resolvedType) {
+ return mComputer.activitySupportsIntent(mResolveComponentName, component, intent,
+ resolvedType);
+ }
+
+ @Override
+ public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
+ int sourceUserId, int targetUserId, int flags) {
+ PackageManagerService.this.addCrossProfileIntentFilter(
+ new WatchedIntentFilter(intentFilter), ownerPackage, sourceUserId, targetUserId,
+ flags);
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public boolean addPermission(PermissionInfo info) {
+ // Because this is accessed via the package manager service AIDL,
+ // go through the permission manager service AIDL
+ return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public boolean addPermissionAsync(PermissionInfo info) {
+ // Because this is accessed via the package manager service AIDL,
+ // go through the permission manager service AIDL
+ return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
+ }
+
+ @Override
+ public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
+ int userId) {
+ mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter),
+ activity, userId);
+ }
+
+ @Override
+ public void addPreferredActivity(IntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
+ mPreferredActivityHelper.addPreferredActivity(new WatchedIntentFilter(filter), match,
+ set, activity, true, userId, "Adding preferred", removeExisting);
+ }
+
+ /*
+ * Returns if intent can be forwarded from the sourceUserId to the targetUserId
+ */
+ @Override
+ public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
+ @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
+ return mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
+ }
+
+ @Override
+ public boolean canRequestPackageInstalls(String packageName, int userId) {
+ return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId,
+ true /* throwIfPermNotDeclared*/);
+ }
+
+ @Override
+ public String[] canonicalToCurrentPackageNames(String[] names) {
+ return mComputer.canonicalToCurrentPackageNames(names);
+ }
+
+ @Override
+ public void checkPackageStartable(String packageName, int userId) {
+ PackageManagerService.this
+ .checkPackageStartable(snapshotComputer(), packageName, userId);
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public int checkPermission(String permName, String pkgName, int userId) {
+ return PackageManagerService.this.checkPermission(permName, pkgName, userId);
+ }
+
+ @Override
+ public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
+ return mComputer.checkSignatures(pkg1, pkg2);
+ }
+
+ @Override
+ public int checkUidPermission(String permName, int uid) {
+ return mComputer.checkUidPermission(permName, uid);
+ }
+
+ @Override
+ public int checkUidSignatures(int uid1, int uid2) {
+ return mComputer.checkUidSignatures(uid1, uid2);
+ }
+
+ @Override
+ public void clearApplicationProfileData(String packageName) {
+ PackageManagerServiceUtils.enforceSystemOrRoot(
+ "Only the system can clear all profile data");
+
+ final AndroidPackage pkg = getPackage(packageName);
+ try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) {
+ synchronized (mInstallLock) {
+ mAppDataHelper.clearAppProfilesLIF(pkg);
+ }
+ }
+ }
+
+ @Override
+ public void clearApplicationUserData(final String packageName,
+ final IPackageDataObserver observer, final int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CLEAR_APP_USER_DATA, null);
+
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+ false /* checkShell */, "clear application data");
+
+ if (mComputer.getPackageStateFiltered(packageName, callingUid, userId) == null) {
+ if (observer != null) {
+ mHandler.post(() -> {
+ try {
+ observer.onRemoveCompleted(packageName, false);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Observer no longer exists.");
+ }
+ });
+ }
+ return;
+ }
+ if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
+ throw new SecurityException("Cannot clear data for a protected package: "
+ + packageName);
+ }
+
+ // Queue up an async operation since the package deletion may take a little while.
+ mHandler.post(new Runnable() {
+ public void run() {
+ mHandler.removeCallbacks(this);
+ final boolean succeeded;
+ try (PackageFreezer freezer = freezePackage(packageName,
+ "clearApplicationUserData")) {
+ synchronized (mInstallLock) {
+ succeeded = clearApplicationUserDataLIF(packageName, userId);
+ }
+ mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId);
+ synchronized (mLock) {
+ if (succeeded) {
+ resetComponentEnabledSettingsIfNeededLPw(packageName, userId);
+ }
+ }
+ }
+ if (succeeded) {
+ // invoke DeviceStorageMonitor's update method to clear any notifications
+ DeviceStorageMonitorInternal dsm = LocalServices
+ .getService(DeviceStorageMonitorInternal.class);
+ if (dsm != null) {
+ dsm.checkMemory();
+ }
+ if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
+ == PERMISSION_GRANTED) {
+ unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId);
+ removeAllDistractingPackageRestrictions(userId);
+ flushPackageRestrictionsAsUserInternalLocked(userId);
+ }
+ }
+ if (observer != null) {
+ try {
+ observer.onRemoveCompleted(packageName, succeeded);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Observer no longer exists.");
+ }
+ } //end if observer
+ } //end run
+ });
+ }
+
+ @Override
+ public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ final int callingUid = Binder.getCallingUid();
+ enforceOwnerRights(ownerPackage, callingUid);
+ PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
+ UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
+ synchronized (mLock) {
+ CrossProfileIntentResolver resolver =
+ mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
+ ArraySet<CrossProfileIntentFilter> set =
+ new ArraySet<>(resolver.filterSet());
+ for (CrossProfileIntentFilter filter : set) {
+ if (filter.getOwnerPackage().equals(ownerPackage)) {
+ resolver.removeFilter(filter);
+ }
+ }
+ }
+ scheduleWritePackageRestrictions(sourceUserId);
+ }
+
+ @Override
+ public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
+ mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId);
+ }
+
+ @Override
+ public void clearPackagePreferredActivities(String packageName) {
+ mPreferredActivityHelper.clearPackagePreferredActivities(packageName);
+ }
+
+ @Override
+ public String[] currentToCanonicalPackageNames(String[] names) {
+ return mComputer.currentToCanonicalPackageNames(names);
+ }
+
+ @Override
+ public void deleteApplicationCacheFiles(final String packageName,
+ final IPackageDataObserver observer) {
+ final int userId = UserHandle.getCallingUserId();
+ deleteApplicationCacheFilesAsUser(packageName, userId, observer);
+ }
+
+ @Override
+ public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
+ final IPackageDataObserver observer) {
+ final int callingUid = Binder.getCallingUid();
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
+ != PackageManager.PERMISSION_GRANTED) {
+ // If the caller has the old delete cache permission, silently ignore. Else throw.
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.DELETE_CACHE_FILES)
+ == PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
+ android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
+ ", silently ignoring");
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
+ }
+ enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
+ /* checkShell= */ false, "delete application cache files");
+ final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_INSTANT_APPS);
+
+ final AndroidPackage pkg = getPackage(packageName);
+
+ // Queue up an async operation since the package deletion may take a little while.
+ mHandler.post(() -> {
+ final PackageStateInternal ps =
+ pkg == null ? null : getPackageStateInternal(pkg.getPackageName());
+ boolean doClearData = true;
+ if (ps != null) {
+ final boolean targetIsInstantApp =
+ ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp();
+ doClearData = !targetIsInstantApp
+ || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
+ }
+ if (doClearData) {
+ synchronized (mInstallLock) {
+ final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
+ // We're only clearing cache files, so we don't care if the
+ // app is unfrozen and still able to run
+ mAppDataHelper.clearAppDataLIF(pkg, userId,
+ flags | Installer.FLAG_CLEAR_CACHE_ONLY);
+ mAppDataHelper.clearAppDataLIF(pkg, userId,
+ flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ }
+ }
+ if (observer != null) {
+ try {
+ observer.onRemoveCompleted(packageName, true);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Observer no longer exists.");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
+ final IPackageDeleteObserver2 observer, final int userId) {
+ PackageManagerService.this.deleteExistingPackageAsUser(versionedPackage, observer,
+ userId);
+ }
+
+ @Override
+ public void deletePackageAsUser(String packageName, int versionCode,
+ IPackageDeleteObserver observer, int userId, int flags) {
+ deletePackageVersioned(new VersionedPackage(packageName, versionCode),
+ new PackageManager.LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
+ }
+
+ @Override
+ public void deletePackageVersioned(VersionedPackage versionedPackage,
+ final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
+ PackageManagerService.this.deletePackageVersioned(versionedPackage, observer,
+ userId, deleteFlags);
+ }
+
+ @Override
+ public void deletePreloadsFileCache() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
+ "deletePreloadsFileCache");
+ File dir = Environment.getDataPreloadsFileCacheDirectory();
+ Slog.i(PackageManagerService.TAG, "Deleting preloaded file cache " + dir);
+ FileUtils.deleteContents(dir);
+ }
+
+ @Override
+ public void dumpProfiles(String packageName) {
+ /* Only the shell, root, or the app user should be able to dump profiles. */
+ final int callingUid = Binder.getCallingUid();
+ final String[] callerPackageNames = getPackagesForUid(callingUid);
+ if (callingUid != Process.SHELL_UID
+ && callingUid != Process.ROOT_UID
+ && !ArrayUtils.contains(callerPackageNames, packageName)) {
+ throw new SecurityException("dumpProfiles");
+ }
+
+ AndroidPackage pkg = mComputer.getPackage(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+
+ synchronized (mInstallLock) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
+ mArtManagerService.dumpProfiles(pkg);
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ @Override
+ public void enterSafeMode() {
+ PackageManagerServiceUtils.enforceSystemOrRoot(
+ "Only the system can request entering safe mode");
+
+ if (!mSystemReady) {
+ mSafeMode = true;
+ }
+ }
+
+ @Override
+ public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+ long millisecondsToDelay) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+ "Only package verification agents can extend verification timeouts");
+ final int callingUid = Binder.getCallingUid();
+
+ mHandler.post(() -> {
+ final PackageVerificationState state = mPendingVerification.get(id);
+ final PackageVerificationResponse response = new PackageVerificationResponse(
+ verificationCodeAtTimeout, callingUid);
+
+ long delay = millisecondsToDelay;
+ if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
+ delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
+ }
+ if (delay < 0) {
+ delay = 0;
+ }
+
+ if ((state != null) && !state.timeoutExtended()) {
+ state.extendTimeout();
+
+ final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
+ msg.arg1 = id;
+ msg.obj = response;
+ mHandler.sendMessageDelayed(msg, delay);
+ }
+ });
+ }
+
+ @Override
+ public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
+ return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId);
+ }
+
+ @Override
+ public void finishPackageInstall(int token, boolean didLaunch) {
+ PackageManagerServiceUtils.enforceSystemOrRoot(
+ "Only the system is allowed to finish installs");
+
+ if (PackageManagerService.DEBUG_INSTALL) {
+ Slog.v(PackageManagerService.TAG, "BM finishing package install for " + token);
+ }
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
+
+ final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token, didLaunch ? 1 : 0);
+ mHandler.sendMessage(msg);
+ }
+
+ @WorkerThread
+ @Override
+ public void flushPackageRestrictionsAsUser(int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
+ if (!mUserManager.exists(userId)) {
+ return;
+ }
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
+ false /* checkShell */, "flushPackageRestrictions");
+ synchronized (mLock) {
+ flushPackageRestrictionsAsUserInternalLocked(userId);
+ }
+ }
+
+ @Override
+ public void forceDexOpt(String packageName) {
+ mDexOptHelper.forceDexOpt(packageName);
+ }
+
+
+ @Override
+ public void freeStorage(final String volumeUuid, final long freeStorageSize,
+ final @StorageManager.AllocateFlags int flags, final IntentSender pi) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CLEAR_APP_CACHE, TAG);
+ mHandler.post(() -> {
+ boolean success = false;
+ try {
+ PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags);
+ success = true;
+ } catch (IOException e) {
+ Slog.w(TAG, e);
+ }
+ if (pi != null) {
+ try {
+ pi.sendIntent(null, success ? 1 : 0, null, null, null);
+ } catch (SendIntentException e) {
+ Slog.w(TAG, e);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
+ final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CLEAR_APP_CACHE, null);
+ mHandler.post(() -> {
+ boolean success = false;
+ try {
+ PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags);
+ success = true;
+ } catch (IOException e) {
+ Slog.w(PackageManagerService.TAG, e);
+ }
+ if (observer != null) {
+ try {
+ observer.onRemoveCompleted(null, success);
+ } catch (RemoteException e) {
+ Slog.w(PackageManagerService.TAG, e);
+ }
+ }
+ });
+ }
+
+ @Override
+ public ActivityInfo getActivityInfo(ComponentName component,
+ @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+ return mComputer.getActivityInfo(component, flags, userId);
+ }
+
+ @NonNull
+ @Override
+ public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
+ return mComputer.getAllIntentFilters(packageName);
+ }
+
+ @Override
+ public List<String> getAllPackages() {
+ return mComputer.getAllPackages();
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @NonNull
+ @Override
+ public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
+ return mComputer.getAppOpPermissionPackages(permissionName);
+ }
+
+ @Override
+ public String getAppPredictionServicePackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultAppPredictionService));
+ }
+
+ @PackageManager.EnabledState
+ @Override
+ public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
+ return mComputer.getApplicationEnabledSetting(packageName, userId);
+ }
+
+ /**
+ * Returns true if application is not found or there was an error. Otherwise it returns
+ * the hidden state of the package for the given user.
+ */
+ @Override
+ public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
+ @UserIdInt int userId) {
+ return mComputer.getApplicationHiddenSettingAsUser(packageName, userId);
+ }
+
+ @Override
+ public ApplicationInfo getApplicationInfo(String packageName,
+ @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
+ return mComputer.getApplicationInfo(packageName, flags, userId);
+ }
+
+ @Override
+ public IArtManager getArtManager() {
+ return mArtManagerService;
+ }
+
+ @Override
+ public @Nullable String getAttentionServicePackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultAttentionService));
+ }
+
+ @Override
+ public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
+ return mComputer.getBlockUninstallForUser(packageName, userId);
+ }
+
+ @Override
+ public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
+ return null;
+ }
+ if (!mUserManager.exists(userId)) {
+ return null;
+ }
+ enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
+ final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages(
+ sequenceNumber, userId);
+
+ if (changedPackages != null) {
+ final List<String> packageNames = changedPackages.getPackageNames();
+ for (int index = packageNames.size() - 1; index >= 0; index--) {
+ // Filter out the changes if the calling package should not be able to see it.
+ final PackageSetting ps = mSettings.getPackageLPr(packageNames.get(index));
+ if (shouldFilterApplication(ps, callingUid, userId)) {
+ packageNames.remove(index);
+ }
+ }
+ }
+
+ return changedPackages;
+ }
+
+ @Override
+ public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
+ return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
+ }
+
+ @Override
+ public String getContentCaptureServicePackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultContentCaptureService));
+ }
+
+ @Nullable
+ @Override
+ public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
+ @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
+ @NonNull int userId) {
+ return mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
+ }
+
+ /**
+ * Non-Binder method, support for the backup/restore mechanism: write the
+ * default browser (etc) settings in its canonical XML format. Returns the default
+ * browser XML representation as a byte array, or null if there is none.
+ */
+ @Override
+ public byte[] getDefaultAppsBackup(int userId) {
+ return mPreferredActivityHelper.getDefaultAppsBackup(userId);
+ }
+
+ @Override
+ public String getDefaultTextClassifierPackageName() {
+ return ensureSystemPackageName(
+ mContext.getString(R.string.config_servicesExtensionPackage));
+ }
+
+ @Override
+ public byte[] getDomainVerificationBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getDomainVerificationBackup()");
+ }
+
+ try {
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+ TypedXmlSerializer serializer = Xml.resolveSerializer(output);
+ mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true,
+ userId);
+ return output.toByteArray();
+ }
+ } catch (Exception e) {
+ if (PackageManagerService.DEBUG_BACKUP) {
+ Slog.e(PackageManagerService.TAG, "Unable to write domain verification for backup", e);
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public int getFlagsForUid(int uid) {
+ return mComputer.getFlagsForUid(uid);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
+ return mComputer.getHarmfulAppWarning(packageName, userId);
+ }
+
+ @Override
+ public IBinder getHoldLockToken() {
+ if (!Build.IS_DEBUGGABLE) {
+ throw new SecurityException("getHoldLockToken requires a debuggable build");
+ }
+
+ mContext.enforceCallingPermission(
+ Manifest.permission.INJECT_EVENTS,
+ "getHoldLockToken requires INJECT_EVENTS permission");
+
+ final Binder token = new Binder();
+ token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
+ return token;
+ }
+
+ @Override
+ public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
+ return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
+ }
+
+ public String getIncidentReportApproverPackageName() {
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_incidentReportApproverPackage));
+ }
+
+ @Override
+ public int getInstallLocation() {
+ // allow instant app access
+ return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
+ InstallLocationUtils.APP_INSTALL_AUTO);
+ }
+
+ @PackageManager.InstallReason
+ @Override
+ public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
+ return mComputer.getInstallReason(packageName, userId);
+ }
+
+ @Override
+ @Nullable
+ public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
+ return mComputer.getInstallSourceInfo(packageName);
+ }
+
+ @Override
+ public ParceledListSlice<ApplicationInfo> getInstalledApplications(
+ @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ return new ParceledListSlice<>(
+ mComputer.getInstalledApplications(flags, userId, callingUid));
+ }
+
+ @Override
+ public List<ModuleInfo> getInstalledModules(int flags) {
+ return mModuleInfoProvider.getInstalledModules(flags);
+ }
+
+ @Override
+ public ParceledListSlice<PackageInfo> getInstalledPackages(
+ @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+ return mComputer.getInstalledPackages(flags, userId);
+ }
+
+ @Nullable
+ @Override
+ public String getInstallerPackageName(@NonNull String packageName) {
+ return mComputer.getInstallerPackageName(packageName);
+ }
+
+ @Override
+ public String getInstantAppAndroidId(String packageName, int userId) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
+ "getInstantAppAndroidId");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, false /* checkShell */,
+ "getInstantAppAndroidId");
+ // Make sure the target is an Instant App.
+ if (!isInstantApp(packageName, userId)) {
+ return null;
+ }
+ return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId);
+ }
+
+ @Override
+ public byte[] getInstantAppCookie(String packageName, int userId) {
+ if (HIDE_EPHEMERAL_APIS) {
+ return null;
+ }
+
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, false /* checkShell */,
+ "getInstantAppCookie");
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
+ return null;
+ }
+ PackageStateInternal packageState = getPackageStateInternal(packageName);
+ if (packageState == null || packageState.getPkg() == null) {
+ return null;
+ }
+ return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId);
+ }
+
+ @Override
+ public Bitmap getInstantAppIcon(String packageName, int userId) {
+ if (HIDE_EPHEMERAL_APIS) {
+ return null;
+ }
+
+ if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+ "getInstantAppIcon");
+ }
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, false /* checkShell */,
+ "getInstantAppIcon");
+
+ return mInstantAppRegistry.getInstantAppIcon(packageName, userId);
+ }
+
+ @Override
+ public ComponentName getInstantAppInstallerComponent() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
+ return mInstantAppInstallerActivity == null
+ ? null : mInstantAppInstallerActivity.getComponentName();
+ }
+
+ @Override
+ public @Nullable ComponentName getInstantAppResolverComponent() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
+ return getInstantAppResolver();
+ }
+
+ @Override
+ public ComponentName getInstantAppResolverSettingsComponent() {
+ return mInstantAppResolverSettingsComponent;
+ }
+
+ @Override
+ public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
+ if (PackageManagerService.HIDE_EPHEMERAL_APIS) {
+ return null;
+ }
+ if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+ "getEphemeralApplications");
+ }
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, false /* checkShell */,
+ "getEphemeralApplications");
+
+ Computer computer = snapshotComputer();
+ List<InstantAppInfo> instantApps = mInstantAppRegistry.getInstantApps(computer, userId);
+ if (instantApps != null) {
+ return new ParceledListSlice<>(instantApps);
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
+ return mComputer.getInstrumentationInfo(component, flags);
+ }
+
+ @Deprecated
+ @Override
+ public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
+ String packageName) {
+ return ParceledListSlice.emptyList();
+ }
+
+ @Deprecated
+ @Override
+ public int getIntentVerificationStatus(String packageName, int userId) {
+ return mDomainVerificationManager.getLegacyState(packageName, userId);
+ }
+
+ @Nullable
+ @Override
+ public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
+ return mComputer.getKeySetByAlias(packageName, alias);
+ }
+
+ @Override
+ public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
+ return mPreferredActivityHelper.getLastChosenActivity(intent, resolvedType, flags);
+ }
+
+ @Override
+ public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
+ String featureId, int userId) throws RemoteException {
+ return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(),
+ packageName, callingPackage, featureId, userId);
+ }
+
+ @Override
+ public List<String> getMimeGroup(String packageName, String mimeGroup) {
+ enforceOwnerRights(packageName, Binder.getCallingUid());
+ return getMimeGroupInternal(packageName, mimeGroup);
+ }
+
+ @Override
+ public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) {
+ return PackageManagerService.this.getModuleInfo(packageName, flags);
+ }
+
+ @Override
+ public int getMoveStatus(int moveId) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ return mMoveCallbacks.mLastStatus.get(moveId);
+ }
+
+ @Nullable
+ @Override
+ public String getNameForUid(int uid) {
+ return mComputer.getNameForUid(uid);
+ }
+
+ @Nullable
+ @Override
+ public String[] getNamesForUids(@NonNull int[] uids) {
+ return mComputer.getNamesForUids(uids);
+ }
+
+ @Override
+ public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags,
+ int userId) {
+ return mComputer.getPackageGids(packageName, flags, userId);
+ }
+
+ @Override
+ public PackageInfo getPackageInfo(String packageName,
+ @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+ return mComputer.getPackageInfo(packageName, flags, userId);
+ }
+
+ @Override
+ public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
+ @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+ return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(),
+ versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
+ }
+
+ @Override
+ public IPackageInstaller getPackageInstaller() {
+ // Return installer service for internal calls.
+ if (PackageManagerServiceUtils.isSystemOrRoot()) {
+ return mInstallerService;
+ }
+ // Return null for InstantApps.
+ if (snapshotComputer().getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
+ return mInstallerService;
+ }
+
+ @Override
+ public void getPackageSizeInfo(final String packageName, int userId,
+ final IPackageStatsObserver observer) {
+ throw new UnsupportedOperationException(
+ "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
+ }
+
+ @Override
+ public int getPackageUid(@NonNull String packageName,
+ @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
+ return mComputer.getPackageUid(packageName, flags, userId);
+ }
+
+ /**
+ * <em>IMPORTANT:</em> Not all packages returned by this method may be known
+ * to the system. There are two conditions in which this may occur:
+ * <ol>
+ * <li>The package is on adoptable storage and the device has been removed</li>
+ * <li>The package is being removed and the internal structures are partially updated</li>
+ * </ol>
+ * The second is an artifact of the current data structures and should be fixed. See
+ * b/111075456 for one such instance.
+ * This binder API is cached. If the algorithm in this method changes,
+ * or if the underlying objecs (as returned by getSettingLPr()) change
+ * then the logic that invalidates the cache must be revisited. See
+ * calls to invalidateGetPackagesForUidCache() to locate the points at
+ * which the cache is invalidated.
+ */
+ @Override
+ public String[] getPackagesForUid(int uid) {
+ final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getUserId(uid);
+ mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
+ /* requireFullPermission */ false,
+ /* checkShell */ false, "getPackagesForUid");
+ return mComputer.getPackagesForUid(uid);
+ }
+
+ @Override
+ public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
+ @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
+ @UserIdInt int userId) {
+ return mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
+ }
+
+ @Override
+ public String getPermissionControllerPackageName() {
+ final int callingUid = Binder.getCallingUid();
+ if (mComputer.getPackageStateFiltered(mRequiredPermissionControllerPackage,
+ callingUid, UserHandle.getUserId(callingUid)) != null) {
+ return mRequiredPermissionControllerPackage;
+ }
+
+ throw new IllegalStateException("PermissionController is not found");
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
+ return PackageManagerService.this.getPermissionGroupInfo(groupName, flags);
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
+ return new ParceledListSlice<>(mComputer.getPersistentApplications(mSafeMode, flags));
+ }
+
+ @Override
+ public int getPreferredActivities(List<IntentFilter> outFilters,
+ List<ComponentName> outActivities, String packageName) {
+ return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities,
+ packageName, snapshotComputer());
+ }
+
+ /**
+ * Non-Binder method, support for the backup/restore mechanism: write the
+ * full set of preferred activities in its canonical XML format. Returns the
+ * XML output as a byte array, or null if there is none.
+ */
+ @Override
+ public byte[] getPreferredActivityBackup(int userId) {
+ return mPreferredActivityHelper.getPreferredActivityBackup(userId);
+ }
+
+ @Override
+ public int getPrivateFlagsForUid(int uid) {
+ return mComputer.getPrivateFlagsForUid(uid);
+ }
+
+ @Override
+ public PackageManager.Property getProperty(String propertyName, String packageName, String className) {
+ Objects.requireNonNull(propertyName);
+ Objects.requireNonNull(packageName);
+ PackageStateInternal packageState = mComputer.getPackageStateFiltered(packageName,
+ Binder.getCallingUid(), UserHandle.getCallingUserId());
+ if (packageState == null) {
+ return null;
+ }
+ return mPackageProperty.getProperty(propertyName, packageName, className);
+ }
+
+ @Nullable
+ @Override
+ public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+ @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+ return mComputer.getProviderInfo(component, flags, userId);
+ }
+
+ @Override
+ public ActivityInfo getReceiverInfo(ComponentName component,
+ @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+ return mComputer.getReceiverInfo(component, flags, userId);
+ }
+
+ @Override
+ public @Nullable String getRotationResolverPackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultRotationResolverService));
+ }
+
+ @Override
+ public int getRuntimePermissionsVersion(@UserIdInt int userId) {
+ Preconditions.checkArgumentNonnegative(userId);
+ enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
+ "getRuntimePermissionVersion");
+ return mSettings.getDefaultRuntimePermissionsVersion(userId);
+ }
+
+ @Nullable
+ @Override
+ public ServiceInfo getServiceInfo(@NonNull ComponentName component,
+ @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+ return mComputer.getServiceInfo(component, flags, userId);
+ }
+
+ @Override
+ public @NonNull String getServicesSystemSharedLibraryPackageName() {
+ return mServicesExtensionPackageName;
+ }
+
+ @Override
+ public String getSetupWizardPackageName() {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Non-system caller");
+ }
+ return mPmInternal.getSetupWizardPackageName();
+ }
+
+ @Override
+ public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
+ @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+ return mComputer.getSharedLibraries(packageName, flags, userId);
+ }
+
+ @Override
+ public @NonNull String getSharedSystemSharedLibraryPackageName() {
+ return mSharedSystemSharedLibraryPackageName;
+ }
+
+ @Nullable
+ @Override
+ public KeySet getSigningKeySet(@NonNull String packageName) {
+ return mComputer.getSigningKeySet(packageName);
+ }
+
+ @Override
+ public String getSplashScreenTheme(@NonNull String packageName, int userId) {
+ PackageStateInternal packageState =
+ getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId);
+ return packageState == null ? null
+ : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
+ }
+
+ @Override
+ public String getSdkSandboxPackageName() {
+ return mRequiredSdkSandboxPackage;
+ }
+
+ @Override
+ public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (getPackageUid(packageName, 0, userId) != callingUid) {
+ throw new SecurityException("Calling package " + packageName
+ + " does not belong to calling uid " + callingUid);
+ }
+ return mSuspendPackageHelper.getSuspendedPackageAppExtras(
+ packageName, userId, callingUid);
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
+ // allow instant applications
+ ArrayList<FeatureInfo> res;
+ synchronized (mAvailableFeatures) {
+ res = new ArrayList<>(mAvailableFeatures.size() + 1);
+ res.addAll(mAvailableFeatures.values());
+ }
+ final FeatureInfo fi = new FeatureInfo();
+ fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
+ FeatureInfo.GL_ES_VERSION_UNDEFINED);
+ res.add(fi);
+
+ return new ParceledListSlice<>(res);
+ }
+
+ @Override
+ public String getSystemCaptionsServicePackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
+ }
+
+ @Nullable
+ @Override
+ public String[] getSystemSharedLibraryNames() {
+ return mComputer.getSystemSharedLibraryNames();
+ }
+
+ @Override
+ public String getSystemTextClassifierPackageName() {
+ return ensureSystemPackageName(
+ mContext.getString(R.string.config_defaultTextClassifierPackage));
+ }
+
+ @Override
+ public int getTargetSdkVersion(@NonNull String packageName) {
+ return mComputer.getTargetSdkVersion(packageName);
+ }
+
+ @Override
+ public int getUidForSharedUser(@NonNull String sharedUserName) {
+ return mComputer.getUidForSharedUser(sharedUserName);
+ }
+
+ @Override
+ public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
+ Objects.requireNonNull(packageNames, "packageNames cannot be null");
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+ "getUnsuspendablePackagesForUser");
+ final int callingUid = Binder.getCallingUid();
+ if (UserHandle.getUserId(callingUid) != userId) {
+ throw new SecurityException("Calling uid " + callingUid
+ + " cannot query getUnsuspendablePackagesForUser for user " + userId);
+ }
+ return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(),
+ packageNames, userId, callingUid);
+ }
+
+ @Override
+ public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+ "Only package verification agents can read the verifier device identity");
+
+ synchronized (mLock) {
+ return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
+ }
+ }
+
+ @Override
+ public String getWellbeingPackageName() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return CollectionUtils.firstOrNull(
+ mContext.getSystemService(RoleManager.class).getRoleHolders(
+ RoleManager.ROLE_SYSTEM_WELLBEING));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void grantImplicitAccess(int recipientUid, @NonNull String visibleAuthority) {
+ final Computer snapshot = snapshotComputer();
+ final int recipientUserId = UserHandle.getUserId(recipientUid);
+ final ProviderInfo providerInfo =
+ snapshot.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority);
+ if (providerInfo == null) {
+ return;
+ }
+ int visibleUid = providerInfo.applicationInfo.uid;
+ PackageManagerService.this.grantImplicitAccess(snapshot, recipientUserId,
+ null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid,
+ false /*direct*/, false /* retainOnUpdate */);
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public void grantRuntimePermission(String packageName, String permName, final int userId) {
+ // Because this is accessed via the package manager service AIDL,
+ // go through the permission manager service AIDL
+ mContext.getSystemService(PermissionManager.class)
+ .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
+ }
+
+ @Override
+ public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
+ @PackageManager.CertificateInputType int type) {
+ return mComputer.hasSigningCertificate(packageName, certificate, type);
+ }
+
+ @Override
+ public boolean hasSystemFeature(String name, int version) {
+ return PackageManagerService.this.hasSystemFeature(name, version);
+ }
+
+ @Override
+ public boolean hasSystemUidErrors() {
+ // allow instant applications
+ return false;
+ }
+
+ @Override
+ public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
+ @PackageManager.CertificateInputType int type) {
+ return mComputer.hasUidSigningCertificate(uid, certificate, type);
+ }
+
+ @Override
+ public void holdLock(IBinder token, int durationMs) {
+ mTestUtilityService.verifyHoldLockToken(token);
+
+ synchronized (mLock) {
+ SystemClock.sleep(durationMs);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
+ int installReason, List<String> whiteListedPermissions) {
+ return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
+ installReason, whiteListedPermissions, null);
+ }
+
+ @Override
+ public boolean isAutoRevokeWhitelisted(String packageName) {
+ int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
+ AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
+ Binder.getCallingUid(), packageName);
+ return mode == MODE_IGNORED;
+ }
+
+ @Override
+ public boolean isDeviceUpgrading() {
+ return PackageManagerService.this.isDeviceUpgrading();
+ }
+
+ @Override
+ public boolean isFirstBoot() {
+ return PackageManagerService.this.isFirstBoot();
+ }
+
+ @Override
+ public boolean isInstantApp(String packageName, int userId) {
+ return mComputer.isInstantApp(packageName, userId);
+ }
+
+ @Override
+ public boolean isOnlyCoreApps() {
+ return PackageManagerService.this.isOnlyCoreApps();
+ }
+
+ @Override
+ public boolean isPackageAvailable(String packageName, int userId) {
+ return mComputer.isPackageAvailable(packageName, userId);
+ }
+
+ @Override
+ public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
+ return PackageManagerService.this.isPackageDeviceAdminOnAnyUser(packageName);
+ }
+
+ @Override
+ public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
+ return mComputer.isPackageSignedByKeySet(packageName, ks);
+ }
+
+ @Override
+ public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) {
+ return mComputer.isPackageSignedByKeySetExactly(packageName, ks);
+ }
+
+ @Override
+ public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingAppId = UserHandle.getAppId(callingUid);
+
+ enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
+ true /*checkShell*/, "isPackageStateProtected");
+
+ if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
+ && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
+ throw new SecurityException("Caller must have the "
+ + MANAGE_DEVICE_ADMINS + " permission.");
+ }
+
+ return mProtectedPackages.isPackageStateProtected(userId, packageName);
+ }
+
+ @Override
+ public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
+ return mComputer.isPackageSuspendedForUser(packageName, userId);
+ }
+
+ @Override
+ public boolean isProtectedBroadcast(String actionName) {
+ if (actionName != null) {
+ // TODO: remove these terrible hacks
+ if (actionName.startsWith("android.net.netmon.lingerExpired")
+ || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
+ || actionName.startsWith("com.android.internal.telephony.data-reconnect")
+ || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
+ return true;
+ }
+ }
+ // allow instant applications
+ synchronized (mProtectedBroadcasts) {
+ return mProtectedBroadcasts.contains(actionName);
+ }
+ }
+
+ @Override
+ public boolean isSafeMode() {
+ // allow instant applications
+ return mSafeMode;
+ }
+
+ @Override
+ public boolean isStorageLow() {
+ return PackageManagerService.this.isStorageLow();
+ }
+
+ @Override
+ public boolean isUidPrivileged(int uid) {
+ return mComputer.isUidPrivileged(uid);
+ }
+
+ /**
+ * Logs process start information (including base APK hash) to the security log.
+ * @hide
+ */
+ @Override
+ public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
+ String seinfo, String apkFile, int pid) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
+ if (!SecurityLog.isLoggingEnabled()) {
+ return;
+ }
+ mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
+ processName, uid, seinfo, pid);
+ }
+
+ @Override
+ public int movePackage(final String packageName, final String volumeUuid) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+
+ final int callingUid = Binder.getCallingUid();
+ final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
+ final int moveId = mNextMoveId.getAndIncrement();
+ mHandler.post(() -> {
+ try {
+ MovePackageHelper movePackageHelper =
+ new MovePackageHelper(PackageManagerService.this);
+ movePackageHelper.movePackageInternal(
+ packageName, volumeUuid, moveId, callingUid, user);
+ } catch (PackageManagerException e) {
+ Slog.w(PackageManagerService.TAG, "Failed to move " + packageName, e);
+ mMoveCallbacks.notifyStatusChanged(moveId, e.error);
+ }
+ });
+ return moveId;
+ }
+
+ @Override
+ public int movePrimaryStorage(String volumeUuid) throws RemoteException {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+
+ final int realMoveId = mNextMoveId.getAndIncrement();
+ final Bundle extras = new Bundle();
+ extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
+ mMoveCallbacks.notifyCreated(realMoveId, extras);
+
+ final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
+ @Override
+ public void onCreated(int moveId, Bundle extras) {
+ // Ignored
+ }
+
+ @Override
+ public void onStatusChanged(int moveId, int status, long estMillis) {
+ mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
+ }
+ };
+
+ final StorageManager storage = mInjector.getSystemService(StorageManager.class);
+ storage.setPrimaryStorageUuid(volumeUuid, callback);
+ return realMoveId;
+ }
+
+ @Override
+ public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
+ String loaderIsa) {
+ int callingUid = Binder.getCallingUid();
+ if (PackageManagerService.PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) {
+ Slog.w(PackageManagerService.TAG, "Non System Server process reporting dex loads as system server. uid="
+ + callingUid);
+ // Do not record dex loads from processes pretending to be system server.
+ // Only the system server should be assigned the package "android", so reject calls
+ // that don't satisfy the constraint.
+ //
+ // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
+ // craft calls to this API and pretend to be system server. Doing so poses no particular
+ // danger for dex load reporting or later dexopt, however it is a sensible check to do
+ // in order to verify the expectations.
+ return;
+ }
+
+ int userId = UserHandle.getCallingUserId();
+ ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
+ if (ai == null) {
+ Slog.w(PackageManagerService.TAG, "Loading a package that does not exist for the calling user. package="
+ + loadingPackageName + ", user=" + userId);
+ return;
+ }
+ mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
+ Process.isIsolated(callingUid));
+ }
+
+ @Override
+ public void notifyPackageUse(String packageName, int reason) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final boolean notify;
+ if (getInstantAppPackageName(callingUid) != null) {
+ notify = isCallerSameApp(packageName, callingUid);
+ } else {
+ notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID);
+ }
+ if (!notify) {
+ return;
+ }
+
+ notifyPackageUseInternal(packageName, reason);
+ }
+
+ @Override
+ public void overrideLabelAndIcon(@NonNull ComponentName componentName,
+ @NonNull String nonLocalizedLabel, int icon, int userId) {
+ if (TextUtils.isEmpty(nonLocalizedLabel)) {
+ throw new IllegalArgumentException("Override label should be a valid String");
+ }
+ updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
+ }
+
+ /**
+ * Ask the package manager to perform a dex-opt with the given compiler filter.
+ *
+ * Note: exposed only for the shell command to allow moving packages explicitly to a
+ * definite state.
+ */
+ @Override
+ public boolean performDexOptMode(String packageName,
+ boolean checkProfiles, String targetCompilerFilter, boolean force,
+ boolean bootComplete, String splitName) {
+ return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter,
+ force, bootComplete, splitName);
+ }
+
+ /**
+ * Ask the package manager to perform a dex-opt with the given compiler filter on the
+ * secondary dex files belonging to the given package.
+ *
+ * Note: exposed only for the shell command to allow moving packages explicitly to a
+ * definite state.
+ */
+ @Override
+ public boolean performDexOptSecondary(String packageName, String compilerFilter,
+ boolean force) {
+ return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force);
+ }
+
+ @NonNull
+ @Override
+ public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
+ int uid, @PackageManager.ComponentInfoFlagsBits long flags,
+ @Nullable String metaDataKey) {
+ return mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
+ }
+
+ @NonNull
+ @Override
+ public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
+ @NonNull String targetPackage, int flags) {
+ return mComputer.queryInstrumentation(targetPackage, flags);
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ try {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
+
+ return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent,
+ resolvedType, flags, userId));
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
+ Intent[] specifics, String[] specificTypes, Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
+ snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags,
+ userId));
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
+ snapshotComputer(), intent, resolvedType, flags, userId));
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
+ snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid()));
+ }
+
+ @Override
+ public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ return new ParceledListSlice<>(snapshotComputer().queryIntentServicesInternal(
+ intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
+ }
+
+ @Override
+ public ParceledListSlice<PackageManager.Property> queryProperty(
+ String propertyName, @PackageManager.PropertyLocation int componentType) {
+ Objects.requireNonNull(propertyName);
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getCallingUserId();
+ final List<PackageManager.Property> result =
+ mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
+ final PackageStateInternal ps = getPackageStateInternal(packageName);
+ return shouldFilterApplication(ps, callingUid, callingUserId);
+ });
+ if (result == null) {
+ return ParceledListSlice.emptyList();
+ }
+ return new ParceledListSlice<>(result);
+ }
+
+ @Deprecated
+ public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
+ mComputer.querySyncProviders(mSafeMode, outNames, outInfo);
+ }
+
+ /**
+ * Reconcile the information we have about the secondary dex files belonging to
+ * {@code packageName} and the actual dex files. For all dex files that were
+ * deleted, update the internal records and delete the generated oat files.
+ */
+ @Override
+ public void reconcileSecondaryDexFiles(String packageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ } else if (isInstantAppInternal(
+ packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) {
+ return;
+ }
+ mDexManager.reconcileSecondaryDexFiles(packageName);
+ }
+
+ @Override
+ public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
+ IDexModuleRegisterCallback callback) {
+ int userId = UserHandle.getCallingUserId();
+ ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
+ DexManager.RegisterDexModuleResult result;
+ if (ai == null) {
+ Slog.w(PackageManagerService.TAG, "Registering a dex module for a package that does not exist for the" +
+ " calling user. package=" + packageName + ", user=" + userId);
+ result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
+ } else {
+ result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
+ }
+
+ if (callback != null) {
+ mHandler.post(() -> {
+ try {
+ callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
+ } catch (RemoteException e) {
+ Slog.w(PackageManagerService.TAG, "Failed to callback after module registration " + dexModulePath, e);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void registerMoveCallback(IPackageMoveObserver callback) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ mMoveCallbacks.register(callback);
+ }
+
+ // NOTE: Can't remove due to unsupported app usage
+ @Override
+ public void removePermission(String permName) {
+ // Because this is accessed via the package manager service AIDL,
+ // go through the permission manager service AIDL
+ mContext.getSystemService(PermissionManager.class).removePermission(permName);
+ }
+
+ @Override
+ public void replacePreferredActivity(IntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity, int userId) {
+ mPreferredActivityHelper.replacePreferredActivity(new WatchedIntentFilter(filter),
+ match, set, activity, userId);
+ }
+
+ @Override
+ public void resetApplicationPreferences(int userId) {
+ mPreferredActivityHelper.resetApplicationPreferences(userId);
+ }
+
+ @Override
+ public ProviderInfo resolveContentProvider(String name,
+ @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid());
+ }
+
+ @Override
+ public ResolveInfo resolveIntent(Intent intent, String resolvedType,
+ @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType,
+ flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
+ }
+
+ @Override
+ public ResolveInfo resolveService(Intent intent, String resolvedType,
+ @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType,
+ flags, userId, callingUid);
+ }
+
+ @Override
+ public void restoreDefaultApps(byte[] backup, int userId) {
+ mPreferredActivityHelper.restoreDefaultApps(backup, userId);
+ }
+
+ @Override
+ public void restoreDomainVerification(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restorePreferredActivities()");
+ }
+
+ try {
+ ByteArrayInputStream input = new ByteArrayInputStream(backup);
+ TypedXmlPullParser parser = Xml.resolvePullParser(input);
+
+ // User ID input isn't necessary here as it assumes the user integers match and that
+ // the only states inside the backup XML are for the target user.
+ mDomainVerificationManager.restoreSettings(snapshotComputer(), parser);
+ input.close();
+ } catch (Exception e) {
+ if (PackageManagerService.DEBUG_BACKUP) {
+ Slog.e(PackageManagerService.TAG, "Exception restoring domain verification: " + e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
+ updateComponentLabelIcon(componentName, null, null, userId);
+ }
+
+ @Override
+ public void restorePreferredActivities(byte[] backup, int userId) {
+ mPreferredActivityHelper.restorePreferredActivities(backup, userId);
+ }
+
+ @Override
+ public void sendDeviceCustomizationReadyBroadcast() {
+ mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
+ "sendDeviceCustomizationReadyBroadcast");
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ BroadcastHelper.sendDeviceCustomizationReadyBroadcast();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void setApplicationCategoryHint(String packageName, int categoryHint,
+ String callerPackageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
+ mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
+ callerPackageName);
+
+ final PackageStateMutator.InitialState initialState = recordInitialState();
+
+ final FunctionalUtils.ThrowingFunction<Computer, PackageStateMutator.Result>
+ implementation = computer -> {
+ PackageStateInternal packageState = computer.getPackageStateFiltered(packageName,
+ Binder.getCallingUid(), UserHandle.getCallingUserId());
+ if (packageState == null) {
+ throw new IllegalArgumentException("Unknown target package " + packageName);
+ }
+
+ if (!Objects.equals(callerPackageName,
+ packageState.getInstallSource().installerPackageName)) {
+ throw new IllegalArgumentException("Calling package " + callerPackageName
+ + " is not installer for " + packageName);
+ }
+
+ if (packageState.getCategoryOverride() != categoryHint) {
+ return commitPackageStateMutation(initialState,
+ packageName, state -> state.setCategoryOverride(categoryHint));
+ } else {
+ return null;
+ }
+ };
+
+ PackageStateMutator.Result result = implementation.apply(snapshotComputer());
+ if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
+ // TODO: Specific return value of what state changed?
+ // The installer on record might have changed, retry with lock
+ synchronized (mPackageStateWriteLock) {
+ result = implementation.apply(snapshotComputer());
+ }
+ }
+
+ if (result != null && result.isCommitted()) {
+ scheduleWriteSettings();
+ }
+ }
+
+ @Override
+ public void setApplicationEnabledSetting(String appPackageName,
+ int newState, int flags, int userId, String callingPackage) {
+ if (!mUserManager.exists(userId)) return;
+ if (callingPackage == null) {
+ callingPackage = Integer.toString(Binder.getCallingUid());
+ }
+
+ setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(appPackageName, newState, flags)),
+ userId, callingPackage);
+ }
+
+ @Override
+ public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+ int userId) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+ true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
+
+ if (hidden && isPackageDeviceAdmin(packageName, userId)) {
+ Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
+ return false;
+ }
+
+ // Do not allow "android" is being disabled
+ if ("android".equals(packageName)) {
+ Slog.w(TAG, "Cannot hide package: android");
+ return false;
+ }
+
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ final PackageStateInternal packageState =
+ mComputer.getPackageStateFiltered(packageName, callingUid, userId);
+ if (packageState == null) {
+ return false;
+ }
+
+ // Cannot hide static shared libs as they are considered
+ // a part of the using app (emulating static linking). Also
+ // static libs are installed always on internal storage.
+ AndroidPackage pkg = packageState.getPkg();
+ if (pkg != null) {
+ // Cannot hide SDK libs as they are controlled by SDK manager.
+ if (pkg.getSdkLibName() != null) {
+ Slog.w(TAG, "Cannot hide package: " + packageName
+ + " providing SDK library: "
+ + pkg.getSdkLibName());
+ return false;
+ }
+ // Cannot hide static shared libs as they are considered
+ // a part of the using app (emulating static linking). Also
+ // static libs are installed always on internal storage.
+ if (pkg.getStaticSharedLibName() != null) {
+ Slog.w(TAG, "Cannot hide package: " + packageName
+ + " providing static shared library: "
+ + pkg.getStaticSharedLibName());
+ return false;
+ }
+ }
+ // Only allow protected packages to hide themselves.
+ if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId())
+ && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
+ Slog.w(TAG, "Not hiding protected package: " + packageName);
+ return false;
+ }
+
+ if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) {
+ return false;
+ }
+
+ commitPackageStateMutation(null, packageName, packageState1 ->
+ packageState1.userState(userId).setHidden(hidden));
+
+ final PackageStateInternal newPackageState = getPackageStateInternal(packageName);
+
+ if (hidden) {
+ killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg");
+ sendApplicationHiddenForUser(packageName, newPackageState, userId);
+ } else {
+ sendPackageAddedForUser(packageName, newPackageState, userId, DataLoaderType.NONE);
+ }
+
+ scheduleWritePackageRestrictions(userId);
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
+ public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
+ int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.DELETE_PACKAGES, null);
+ PackageStateInternal packageState = getPackageStateInternal(packageName);
+ if (packageState != null && packageState.getPkg() != null) {
+ AndroidPackage pkg = packageState.getPkg();
+ // Cannot block uninstall SDK libs as they are controlled by SDK manager.
+ if (pkg.getSdkLibName() != null) {
+ Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName
+ + " providing SDK library: " + pkg.getSdkLibName());
+ return false;
+ }
+ // Cannot block uninstall of static shared libs as they are
+ // considered a part of the using app (emulating static linking).
+ // Also static libs are installed always on internal storage.
+ if (pkg.getStaticSharedLibName() != null) {
+ Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName
+ + " providing static shared library: " + pkg.getStaticSharedLibName());
+ return false;
+ }
+ }
+ synchronized (mLock) {
+ mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
+ }
+
+ scheduleWritePackageRestrictions(userId);
+ return true;
+ }
+
+ @Override
+ public void setComponentEnabledSetting(ComponentName componentName,
+ int newState, int flags, int userId) {
+ if (!mUserManager.exists(userId)) return;
+
+ setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(componentName, newState, flags)),
+ userId, null /* callingPackage */);
+ }
+
+ @Override
+ public void setComponentEnabledSettings(List<PackageManager.ComponentEnabledSetting> settings, int userId) {
+ if (!mUserManager.exists(userId)) return;
+ if (settings == null || settings.isEmpty()) {
+ throw new IllegalArgumentException("The list of enabled settings is empty");
+ }
+
+ setEnabledSettings(settings, userId, null /* callingPackage */);
+ }
+
+ @Override
+ public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
+ int restrictionFlags, int userId) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+ "setDistractingPackageRestrictionsAsUser");
+
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
+ && UserHandle.getUserId(callingUid) != userId) {
+ throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
+ + userId);
+ }
+ Objects.requireNonNull(packageNames, "packageNames cannot be null");
+ if (restrictionFlags != 0
+ && !mSuspendPackageHelper.isSuspendAllowedForUser(userId, callingUid)) {
+ Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId);
+ return packageNames;
+ }
+
+ final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
+ final IntArray changedUids = new IntArray(packageNames.length);
+ final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
+
+ ArraySet<String> changesToCommit = new ArraySet<>();
+ Computer computer = snapshotComputer();
+ final boolean[] canRestrict = (restrictionFlags != 0)
+ ? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId,
+ callingUid) : null;
+ for (int i = 0; i < packageNames.length; i++) {
+ final String packageName = packageNames[i];
+ final PackageStateInternal packageState =
+ computer.getPackageStateInternal(packageName);
+ if (packageState == null
+ || computer.shouldFilterApplication(packageState, callingUid, userId)) {
+ Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName
+ + ". Skipping...");
+ unactionedPackages.add(packageName);
+ continue;
+ }
+ if (canRestrict != null && !canRestrict[i]) {
+ unactionedPackages.add(packageName);
+ continue;
+ }
+ final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
+ .getDistractionFlags();
+ if (restrictionFlags != oldDistractionFlags) {
+ changedPackagesList.add(packageName);
+ changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
+ changesToCommit.add(packageName);
+ }
+ }
+
+ commitPackageStateMutation(null, mutator -> {
+ final int size = changesToCommit.size();
+ for (int index = 0; index < size; index++) {
+ mutator.forPackage(changesToCommit.valueAt(index))
+ .userState(userId)
+ .setDistractionFlags(restrictionFlags);
+ }
+ });
+
+ if (!changedPackagesList.isEmpty()) {
+ final String[] changedPackages = changedPackagesList.toArray(
+ new String[changedPackagesList.size()]);
+ mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged(
+ changedPackages, changedUids.toArray(), userId, restrictionFlags));
+ scheduleWritePackageRestrictions(userId);
+ }
+ return unactionedPackages.toArray(new String[0]);
+ }
+
+ @Override
+ public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
+ int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingAppId = UserHandle.getAppId(callingUid);
+
+ enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
+ true /*checkShell*/, "setHarmfulAppInfo");
+
+ if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
+ checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
+ throw new SecurityException("Caller must have the "
+ + SET_HARMFUL_APP_WARNINGS + " permission.");
+ }
+
+ PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
+ packageState -> packageState.userState(userId)
+ .setHarmfulAppWarning(warning == null ? null : warning.toString()));
+ if (result.isSpecificPackageNull()) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ scheduleWritePackageRestrictions(userId);
+ }
+
+ @Override
+ public void setHomeActivity(ComponentName comp, int userId) {
+ mPreferredActivityHelper.setHomeActivity(comp, userId);
+ }
+
+ @Override
+ public boolean setInstallLocation(int loc) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS,
+ null);
+ if (getInstallLocation() == loc) {
+ return true;
+ }
+ if (loc == InstallLocationUtils.APP_INSTALL_AUTO
+ || loc == InstallLocationUtils.APP_INSTALL_INTERNAL
+ || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) {
+ android.provider.Settings.Global.putInt(mContext.getContentResolver(),
+ android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final FunctionalUtils.ThrowingCheckedFunction<Computer, Boolean, RuntimeException>
+ implementation = computer -> {
+ if (computer.getInstantAppPackageName(callingUid) != null) {
+ return false;
+ }
+
+ PackageStateInternal targetPackageState =
+ computer.getPackageStateInternal(targetPackage);
+ if (targetPackageState == null
+ || computer.shouldFilterApplication(targetPackageState, callingUid,
+ callingUserId)) {
+ throw new IllegalArgumentException("Unknown target package: " + targetPackage);
+ }
+
+ PackageStateInternal installerPackageState = null;
+ if (installerPackageName != null) {
+ installerPackageState = computer.getPackageStateInternal(installerPackageName);
+ if (installerPackageState == null
+ || shouldFilterApplication(
+ installerPackageState, callingUid, callingUserId)) {
+ throw new IllegalArgumentException("Unknown installer package: "
+ + installerPackageName);
+ }
+ }
+
+ Signature[] callerSignature;
+ final int appId = UserHandle.getAppId(callingUid);
+ Pair<PackageStateInternal, SharedUserApi> either =
+ computer.getPackageOrSharedUser(appId);
+ if (either != null) {
+ if (either.first != null) {
+ callerSignature = either.first.getSigningDetails().getSignatures();
+ } else {
+ callerSignature = either.second.getSigningDetails().getSignatures();
+ }
+ } else {
+ throw new SecurityException("Unknown calling UID: " + callingUid);
+ }
+
+ // Verify: can't set installerPackageName to a package that is
+ // not signed with the same cert as the caller.
+ if (installerPackageState != null) {
+ if (compareSignatures(callerSignature,
+ installerPackageState.getSigningDetails().getSignatures())
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as new installer package "
+ + installerPackageName);
+ }
+ }
+
+ // Verify: if target already has an installer package, it must
+ // be signed with the same cert as the caller.
+ String targetInstallerPackageName =
+ targetPackageState.getInstallSource().installerPackageName;
+ PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null
+ ? null : computer.getPackageStateInternal(targetInstallerPackageName);
+
+ if (targetInstallerPkgSetting != null) {
+ if (compareSignatures(callerSignature,
+ targetInstallerPkgSetting.getSigningDetails().getSignatures())
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as old installer package "
+ + targetInstallerPackageName);
+ }
+ } else if (mContext.checkCallingOrSelfPermission(
+ Manifest.permission.INSTALL_PACKAGES) != PERMISSION_GRANTED) {
+ // This is probably an attempt to exploit vulnerability b/150857253 of taking
+ // privileged installer permissions when the installer has been uninstalled or
+ // was never set.
+ EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
+
+ final long binderToken = Binder.clearCallingIdentity();
+ try {
+ if (mInjector.getCompatibility().isChangeEnabledByUid(
+ PackageManagerService.THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
+ callingUid)) {
+ throw new SecurityException("Neither user " + callingUid
+ + " nor current process has "
+ + Manifest.permission.INSTALL_PACKAGES);
+ } else {
+ // If change disabled, fail silently for backwards compatibility
+ return false;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(binderToken);
+ }
+ }
+
+ return true;
+ };
+ PackageStateMutator.InitialState initialState = recordInitialState();
+ boolean allowed = implementation.apply(snapshotComputer());
+ if (allowed) {
+ // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
+ // should find an alternative which avoids any race conditions
+ PackageStateInternal targetPackageState;
+ synchronized (mLock) {
+ PackageStateMutator.Result result = commitPackageStateMutation(initialState,
+ targetPackage, state -> state.setInstaller(installerPackageName));
+ if (result.isPackagesChanged() || result.isStateChanged()) {
+ synchronized (mPackageStateWriteLock) {
+ allowed = implementation.apply(snapshotComputer());
+ if (allowed) {
+ commitPackageStateMutation(null, targetPackage,
+ state -> state.setInstaller(installerPackageName));
+ } else {
+ return;
+ }
+ }
+ }
+ targetPackageState = getPackageStateInternal(targetPackage);
+ mSettings.addInstallerPackageNames(targetPackageState.getInstallSource());
+ }
+ mAppsFilter.addPackage(targetPackageState);
+ scheduleWriteSettings();
+ }
+ }
+
+ @Override
+ public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
+ if (HIDE_EPHEMERAL_APIS) {
+ return true;
+ }
+
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, true /* checkShell */,
+ "setInstantAppCookie");
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
+ return false;
+ }
+
+ PackageStateInternal packageState = getPackageStateInternal(packageName);
+ if (packageState == null || packageState.getPkg() == null) {
+ return false;
+ }
+ return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie,
+ mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId);
+ }
+
+ @Override
+ public void setKeepUninstalledPackages(List<String> packageList) {
+ mContext.enforceCallingPermission(
+ Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
+ "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
+ Objects.requireNonNull(packageList);
+
+ setKeepUninstalledPackagesInternal(packageList);
+ }
+
+ @Override
+ public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
+ IntentFilter filter, int match, ComponentName activity) {
+ mPreferredActivityHelper.setLastChosenActivity(intent, resolvedType, flags,
+ new WatchedIntentFilter(filter), match, activity);
+ }
+
+ @Override
+ public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
+ enforceOwnerRights(packageName, Binder.getCallingUid());
+ mimeTypes = CollectionUtils.emptyIfNull(mimeTypes);
+ final PackageStateInternal packageState = getPackageStateInternal(packageName);
+ Set<String> existingMimeTypes = packageState.getMimeGroups().get(mimeGroup);
+ if (existingMimeTypes == null) {
+ throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
+ + " for package " + packageName);
+ }
+ if (existingMimeTypes.size() == mimeTypes.size()
+ && existingMimeTypes.containsAll(mimeTypes)) {
+ return;
+ }
+
+ ArraySet<String> mimeTypesSet = new ArraySet<>(mimeTypes);
+ commitPackageStateMutation(null, packageName, packageStateWrite -> {
+ packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
+ });
+ if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
+ Binder.withCleanCallingIdentity(() ->
+ mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
+ UserHandle.USER_ALL));
+ }
+
+ scheduleWriteSettings();
+ }
+
+ @Override
+ public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
+ PackageManagerService.this
+ .setPackageStoppedState(snapshotComputer(), packageName, stopped, userId);
+ }
+
+ @Override
+ public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+ PersistableBundle appExtras, PersistableBundle launcherExtras,
+ SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
+ "setPackagesSuspendedAsUser");
+ return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames,
+ suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId,
+ callingUid);
+ }
+
+ @Override
+ public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) {
+ PackageManagerServiceUtils.enforceSystemOrRoot(
+ "setRequiredForSystemUser can only be run by the system or root");
+
+ PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
+ packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser));
+ if (!result.isCommitted()) {
+ return false;
+ }
+
+ scheduleWriteSettings();
+ return true;
+ }
+
+ @Override
+ public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
+ Preconditions.checkArgumentNonnegative(version);
+ Preconditions.checkArgumentNonnegative(userId);
+ enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
+ "setRuntimePermissionVersion");
+ mSettings.setDefaultRuntimePermissionsVersion(version, userId);
+ }
+
+ @Override
+ public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
+ int userId) {
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ false /* checkShell */, "setSplashScreenTheme");
+ enforceOwnerRights(packageName, callingUid);
+
+ PackageStateInternal packageState = getPackageStateInstalledFiltered(packageName,
+ callingUid, userId);
+ if (packageState == null) {
+ return;
+ }
+
+ commitPackageStateMutation(null, packageName, state ->
+ state.userState(userId).setSplashScreenTheme(themeId));
+ }
+
+ @Override
+ public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
+ final int callingUid = Binder.getCallingUid();
+ final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
+ || callingUid == Process.SYSTEM_UID;
+ if (!calledFromSystemOrPhone) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+ "setSystemAppHiddenUntilInstalled");
+ }
+
+ final PackageStateInternal stateRead = getPackageStateInternal(packageName);
+ if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) {
+ return;
+ }
+ if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
+ throw new SecurityException("Only system or phone callers can modify core apps");
+ }
+
+ commitPackageStateMutation(null, mutator -> {
+ mutator.forPackage(packageName)
+ .setHiddenUntilInstalled(hidden);
+ mutator.forDisabledSystemPackage(packageName)
+ .setHiddenUntilInstalled(hidden);
+ });
+ }
+
+ @Override
+ public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
+ || callingUid == Process.SYSTEM_UID;
+ if (!calledFromSystemOrPhone) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+ "setSystemAppHiddenUntilInstalled");
+ }
+
+ final PackageStateInternal packageState = getPackageStateInternal(packageName);
+ // The target app should always be in system
+ if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) {
+ return false;
+ }
+ if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
+ throw new SecurityException("Only system or phone callers can modify core apps");
+ }
+ // Check if the install state is the same
+ if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) {
+ return false;
+ }
+
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ if (installed) {
+ // install the app from uninstalled state
+ installExistingPackageAsUser(
+ packageName,
+ userId,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_DEVICE_SETUP,
+ null);
+ return true;
+ }
+
+ // uninstall the app from installed state
+ deletePackageVersioned(
+ new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+ new PackageManager.LegacyPackageDeleteObserver(null).getBinder(),
+ userId,
+ PackageManager.DELETE_SYSTEM_APP);
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
+ public void setUpdateAvailable(String packageName, boolean updateAvailable) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
+ commitPackageStateMutation(null, packageName, state ->
+ state.setUpdateAvailable(updateAvailable));
+ }
+
+ @Override
+ public void unregisterMoveCallback(IPackageMoveObserver callback) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ mMoveCallbacks.unregister(callback);
+ }
+
+ @Deprecated
+ @Override
+ public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
+ return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
+ }
+
+ @Deprecated
+ @Override
+ public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
+ DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
+ id, verificationCode, failedDomains, Binder.getCallingUid());
+ }
+
+ @Override
+ public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+ "Only package verification agents can verify applications");
+ final int callingUid = Binder.getCallingUid();
+
+ final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
+ final PackageVerificationResponse response = new PackageVerificationResponse(
+ verificationCode, callingUid);
+ msg.arg1 = id;
+ msg.obj = response;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits,
+ @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
+ @Nullable List trustedInstallers,
+ @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
+ requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
+ onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
+ mInjector.getBackgroundHandler());
+ }
+
+ @Override
+ public void notifyPackagesReplacedReceived(String[] packages) {
+ Computer computer = snapshotComputer();
+ ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
+ for (int index = 0; index < packagesToNotify.size(); index++) {
+ notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
+ }
+ }
+
+ @Override
+ public boolean canPackageQuery(@NonNull String sourcePackageName,
+ @NonNull String targetPackageName, @UserIdInt int userId) {
+ return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId);
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ try {
+ return super.onTransact(code, data, reply, flags);
+ } catch (RuntimeException e) {
+ if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)
+ && !(e instanceof ParcelableException)) {
+ Slog.wtf(TAG, "Package Manager Unexpected Exception", e);
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ShellCallback callback,
+ ResultReceiver resultReceiver) {
+ (new PackageManagerShellCommand(mIPackageManager,
+ mContext,mDomainVerificationManager.getShell()))
+ .exec(this, in, out, err, args, callback, resultReceiver);
+ }
+
+ @SuppressWarnings("resource")
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+ new DumpHelper(PackageManagerService.this).doDump(fd, pw, args);
+ }
+ }
+
+ private class PackageManagerLocalImpl implements PackageManagerLocal {
+ }
+
private class PackageManagerInternalImpl extends PackageManagerInternal {
@Override
public List<ApplicationInfo> getInstalledApplications(
@@ -6850,7 +7173,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isInstantApp(String packageName, int userId) {
- return PackageManagerService.this.isInstantApp(packageName, userId);
+ return PackageManagerService.this.mIPackageManager.isInstantApp(packageName, userId);
}
@Override
@@ -7211,7 +7534,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getNameForUid(int uid) {
- return PackageManagerService.this.getNameForUid(uid);
+ return mIPackageManager.getNameForUid(uid);
}
@Override
@@ -7456,7 +7779,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isOnlyCoreApps() {
- return PackageManagerService.this.isOnlyCoreApps();
+ return mIPackageManager.isOnlyCoreApps();
}
@Override
@@ -7466,6 +7789,11 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
+ public void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException {
+ PackageManagerService.this.freeAllAppCacheAboveQuota(volumeUuid);
+ }
+
+ @Override
public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
PackageManagerService.this.forEachPackageSetting(actionLocked);
}
@@ -7543,7 +7871,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void finishPackageInstall(int token, boolean didLaunch) {
- PackageManagerService.this.finishPackageInstall(token, didLaunch);
+ mIPackageManager.finishPackageInstall(token, didLaunch);
}
@Nullable
@@ -7788,6 +8116,16 @@ public class PackageManagerService extends IPackageManager.Stub
public Computer snapshot() {
return snapshotComputer();
}
+
+ @Override
+ public void shutdown() {
+ PackageManagerService.this.shutdown();
+ }
+
+ @Override
+ public DynamicCodeLogger getDynamicCodeLogger() {
+ return PackageManagerService.this.getDexManager().getDynamicCodeLogger();
+ }
}
private boolean setEnabledOverlayPackages(@UserIdInt int userId,
@@ -7871,23 +8209,6 @@ public class PackageManagerService extends IPackageManager.Stub
return true;
}
- @Override
- public int getRuntimePermissionsVersion(@UserIdInt int userId) {
- Preconditions.checkArgumentNonnegative(userId);
- enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
- "getRuntimePermissionVersion");
- return mSettings.getDefaultRuntimePermissionsVersion(userId);
- }
-
- @Override
- public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
- Preconditions.checkArgumentNonnegative(version);
- Preconditions.checkArgumentNonnegative(userId);
- enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
- "setRuntimePermissionVersion");
- mSettings.setDefaultRuntimePermissionsVersion(version, userId);
- }
-
private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
@NonNull String message) {
if (mContext.checkCallingOrSelfPermission(
@@ -8016,23 +8337,6 @@ public class PackageManagerService extends IPackageManager.Stub
return mPackageUsage.isHistoricalPackageUsageAvailable();
}
- /**
- * Logs process start information (including base APK hash) to the security log.
- * @hide
- */
- @Override
- public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
- String seinfo, String apkFile, int pid) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return;
- }
- if (!SecurityLog.isLoggingEnabled()) {
- return;
- }
- mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
- processName, uid, seinfo, pid);
- }
-
public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
return getOrCreateCompilerPackageStats(pkg.getPackageName());
}
@@ -8041,26 +8345,6 @@ public class PackageManagerService extends IPackageManager.Stub
return mCompilerStats.getOrCreatePackageStats(pkgName);
}
- @Override
- public boolean isAutoRevokeWhitelisted(String packageName) {
- int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
- AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
- Binder.getCallingUid(), packageName);
- return mode == MODE_IGNORED;
- }
-
- @PackageManager.InstallReason
- @Override
- public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
- return mComputer.getInstallReason(packageName, userId);
- }
-
- @Override
- public boolean canRequestPackageInstalls(String packageName, int userId) {
- return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId,
- true /* throwIfPermNotDeclared*/);
- }
-
/**
* Returns true if the system or user is explicitly preventing an otherwise valid installer to
* complete an install. This includes checks like unknown sources and user restrictions.
@@ -8069,45 +8353,35 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.isInstallDisabledForPackage(packageName, uid, userId);
}
- @Override
- public ComponentName getInstantAppResolverSettingsComponent() {
- return mInstantAppResolverSettingsComponent;
- }
-
- @Override
- public ComponentName getInstantAppInstallerComponent() {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return null;
+ private void grantImplicitAccess(@NonNull Computer snapshot, @UserIdInt int userId,
+ Intent intent, @AppIdInt int recipientAppId, int visibleUid, boolean direct,
+ boolean retainOnUpdate) {
+ final AndroidPackage visiblePackage = snapshot.getPackage(visibleUid);
+ final int recipientUid = UserHandle.getUid(userId, recipientAppId);
+ if (visiblePackage == null || snapshot.getPackage(recipientUid) == null) {
+ return;
}
- return mInstantAppInstallerActivity == null
- ? null : mInstantAppInstallerActivity.getComponentName();
- }
- @Override
- public String getInstantAppAndroidId(String packageName, int userId) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
- "getInstantAppAndroidId");
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
- false /* checkShell */, "getInstantAppAndroidId");
- // Make sure the target is an Instant App.
- if (!isInstantApp(packageName, userId)) {
- return null;
+ final boolean instantApp = snapshot.isInstantAppInternal(
+ visiblePackage.getPackageName(), userId, visibleUid);
+ final boolean accessGranted;
+ if (instantApp) {
+ if (!direct) {
+ // if the interaction that lead to this granting access to an instant app
+ // was indirect (i.e.: URI permission grant), do not actually execute the
+ // grant.
+ return;
+ }
+ accessGranted = mInstantAppRegistry.grantInstantAccess(userId, intent,
+ recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
+ } else {
+ accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid,
+ retainOnUpdate);
}
- return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId);
- }
- @Override
- public void grantImplicitAccess(int recipientUid, @NonNull String visibleAuthority) {
- final int callingUid = Binder.getCallingUid();
- final int recipientUserId = UserHandle.getUserId(recipientUid);
- final ProviderInfo providerInfo =
- mComputer.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority);
- if (providerInfo == null) {
- return;
+ if (accessGranted) {
+ ApplicationPackageManager.invalidateGetPackagesForUidCache();
}
- int visibleUid = providerInfo.applicationInfo.uid;
- mPmInternal.grantImplicitAccess(recipientUserId, null /*Intent*/,
- UserHandle.getAppId(recipientUid), visibleUid, false /*direct*/);
}
boolean canHaveOatDir(String packageName) {
@@ -8133,100 +8407,6 @@ public class PackageManagerService extends IPackageManager.Stub
return mComputer.getUnusedPackages(downgradeTimeThresholdMillis);
}
- @Override
- public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
- int userId) {
- final int callingUid = Binder.getCallingUid();
- final int callingAppId = UserHandle.getAppId(callingUid);
-
- enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
- true /*checkShell*/, "setHarmfulAppInfo");
-
- if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
- checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
- throw new SecurityException("Caller must have the "
- + SET_HARMFUL_APP_WARNINGS + " permission.");
- }
-
- PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
- packageState -> packageState.userState(userId)
- .setHarmfulAppWarning(warning == null ? null : warning.toString()));
- if (result.isSpecificPackageNull()) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
- scheduleWritePackageRestrictions(userId);
- }
-
- @Nullable
- @Override
- public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
- return mComputer.getHarmfulAppWarning(packageName, userId);
- }
-
- @Override
- public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
- final int callingUid = Binder.getCallingUid();
- final int callingAppId = UserHandle.getAppId(callingUid);
-
- enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
- true /*checkShell*/, "isPackageStateProtected");
-
- if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
- && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
- throw new SecurityException("Caller must have the "
- + MANAGE_DEVICE_ADMINS + " permission.");
- }
-
- return mProtectedPackages.isPackageStateProtected(userId, packageName);
- }
-
- @Override
- public void sendDeviceCustomizationReadyBroadcast() {
- mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
- "sendDeviceCustomizationReadyBroadcast");
-
- final long ident = Binder.clearCallingIdentity();
- try {
- BroadcastHelper.sendDeviceCustomizationReadyBroadcast();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
- enforceOwnerRights(packageName, Binder.getCallingUid());
- mimeTypes = CollectionUtils.emptyIfNull(mimeTypes);
- final PackageStateInternal packageState = getPackageStateInternal(packageName);
- Set<String> existingMimeTypes = packageState.getMimeGroups().get(mimeGroup);
- if (existingMimeTypes == null) {
- throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
- + " for package " + packageName);
- }
- if (existingMimeTypes.size() == mimeTypes.size()
- && existingMimeTypes.containsAll(mimeTypes)) {
- return;
- }
-
- ArraySet<String> mimeTypesSet = new ArraySet<>(mimeTypes);
- commitPackageStateMutation(null, packageName, packageStateWrite -> {
- packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
- });
- if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
- Binder.withCleanCallingIdentity(() ->
- mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
- UserHandle.USER_ALL));
- }
-
- scheduleWriteSettings();
- }
-
- @Override
- public List<String> getMimeGroup(String packageName, String mimeGroup) {
- enforceOwnerRights(packageName, Binder.getCallingUid());
- return getMimeGroupInternal(packageName, mimeGroup);
- }
-
private List<String> getMimeGroupInternal(String packageName, String mimeGroup) {
final PackageStateInternal packageState = getPackageStateInternal(packageName);
if (packageState == null) {
@@ -8242,32 +8422,6 @@ public class PackageManagerService extends IPackageManager.Stub
return new ArrayList<>(mimeTypes);
}
- @Override
- public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
- int userId) {
- final int callingUid = Binder.getCallingUid();
- enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
- false /* checkShell */, "setSplashScreenTheme");
- enforceOwnerRights(packageName, callingUid);
-
- PackageStateInternal packageState = getPackageStateInstalledFiltered(packageName,
- callingUid, userId);
- if (packageState == null) {
- return;
- }
-
- commitPackageStateMutation(null, packageName, state ->
- state.userState(userId).setSplashScreenTheme(themeId));
- }
-
- @Override
- public String getSplashScreenTheme(@NonNull String packageName, int userId) {
- PackageStateInternal packageState =
- getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId);
- return packageState == null ? null
- : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
- }
-
/**
* Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's
* writeLegacyPermissionsTEMP() beforehand.
@@ -8281,21 +8435,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public IBinder getHoldLockToken() {
- if (!Build.IS_DEBUGGABLE) {
- throw new SecurityException("getHoldLockToken requires a debuggable build");
- }
-
- mContext.enforceCallingPermission(
- Manifest.permission.INJECT_EVENTS,
- "getHoldLockToken requires INJECT_EVENTS permission");
-
- final Binder token = new Binder();
- token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
- return token;
- }
-
- @Override
public void verifyHoldLockToken(IBinder token) {
if (!Build.IS_DEBUGGABLE) {
throw new SecurityException("holdLock requires a debuggable build");
@@ -8310,15 +8449,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public void holdLock(IBinder token, int durationMs) {
- mTestUtilityService.verifyHoldLockToken(token);
-
- synchronized (mLock) {
- SystemClock.sleep(durationMs);
- }
- }
-
static String getDefaultTimeouts() {
final long token = Binder.clearCallingIdentity();
try {
@@ -8416,16 +8546,6 @@ public class PackageManagerService extends IPackageManager.Stub
return result.toArray(new PerUidReadTimeouts[result.size()]);
}
- @Override
- public void setKeepUninstalledPackages(List<String> packageList) {
- mContext.enforceCallingPermission(
- Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
- "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
- Objects.requireNonNull(packageList);
-
- setKeepUninstalledPackagesInternal(packageList);
- }
-
private void setKeepUninstalledPackagesInternal(List<String> packageList) {
Preconditions.checkNotNull(packageList);
synchronized (mKeepUninstalledPackages) {
@@ -8447,19 +8567,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- @Override
- public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
- String featureId, int userId) throws RemoteException {
- return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(),
- packageName, callingPackage, featureId, userId);
- }
-
- @Override
- public boolean canPackageQuery(@NonNull String sourcePackageName,
- @NonNull String targetPackageName, @UserIdInt int userId) {
- return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId);
- }
-
boolean getSafeMode() {
return mSafeMode;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 500b4ec70c44..b92f51b392f9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -159,9 +159,9 @@ class PackageManagerShellCommand extends ShellCommand {
private static final SecureRandom RANDOM = new SecureRandom();
- PackageManagerShellCommand(@NonNull PackageManagerService service,
+ PackageManagerShellCommand(@NonNull IPackageManager packageManager,
@NonNull Context context, @NonNull DomainVerificationShell domainVerificationShell) {
- mInterface = service;
+ mInterface = packageManager;
mLegacyPermissionManager = LocalServices.getService(LegacyPermissionManagerInternal.class);
mPermissionManager = context.getSystemService(PermissionManager.class);
mContext = context;
diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
index cdaf99c3c68b..fdad83347f24 100644
--- a/services/core/java/com/android/server/pm/PackageRemovedInfo.java
+++ b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
@@ -51,6 +51,7 @@ final class PackageRemovedInfo {
boolean mDataRemoved;
boolean mRemovedForAllUsers;
boolean mIsStaticSharedLib;
+ boolean mIsExternal;
// a two dimensional array mapping userId to the set of appIds that can receive notice
// of package changes
SparseArray<int[]> mBroadcastAllowList;
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index f06ae1e06187..2bae00f91b82 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -477,6 +477,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
public void setSharedUserAppId(int sharedUserAppId) {
mSharedUserAppId = sharedUserAppId;
+ onChanged();
}
@Override
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index 8c49bafa06a8..7253ae4e7cb0 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -151,7 +151,8 @@ final class PreferredActivityHelper {
if (TextUtils.equals(currentPackageName, packageName)) {
return false;
}
- final String[] callingPackages = mPm.getPackagesForUid(Binder.getCallingUid());
+ final String[] callingPackages = mPm.mIPackageManager
+ .getPackagesForUid(Binder.getCallingUid());
if (callingPackages != null && ArrayUtils.contains(callingPackages,
mPm.mRequiredPermissionControllerPackage)) {
// PermissionController manages default home directly.
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 079903e09ba8..88df843ec8c5 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -239,6 +239,7 @@ final class RemovePackageHelper {
&& deletedPkg.getStaticSharedLibName() != null;
outInfo.populateUsers(deletedPs.queryInstalledUsers(
mUserManagerInternal.getUserIds(), true), deletedPs);
+ outInfo.mIsExternal = deletedPs.isExternalStorage();
}
removePackageLI(deletedPs.getPackageName(), (flags & PackageManager.DELETE_CHATTY) != 0);
@@ -283,7 +284,11 @@ final class RemovePackageHelper {
List<AndroidPackage> sharedUserPkgs =
sus != null ? sus.getPackages() : Collections.emptyList();
mPermissionManager.onPackageUninstalled(packageName, deletedPs.getAppId(),
- deletedPs.getPkg(), sharedUserPkgs, UserHandle.USER_ALL);
+ deletedPkg, sharedUserPkgs, UserHandle.USER_ALL);
+ // After permissions are handled, check if the shared user can be migrated
+ if (sus != null) {
+ mPm.mSettings.checkAndConvertSharedUserSettingsLPw(sus);
+ }
}
mPm.clearPackagePreferredActivitiesLPw(
deletedPs.getPackageName(), changedUsers, UserHandle.USER_ALL);
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 33f0b54fb2de..4e8313bf1891 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -165,25 +165,15 @@ final class ScanPackageUtils {
}
}
- int previousAppId = Process.INVALID_UID;
-
if (pkgSetting != null && oldSharedUserSetting != sharedUserSetting) {
- if (oldSharedUserSetting != null && sharedUserSetting == null) {
- previousAppId = pkgSetting.getAppId();
- // Log that something is leaving shareduid and keep going
- Slog.i(TAG,
- "Package " + parsedPackage.getPackageName() + " shared user changed from "
- + oldSharedUserSetting.name + " to " + "<nothing>.");
- } else {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Package " + parsedPackage.getPackageName() + " shared user changed from "
- + (oldSharedUserSetting != null
- ? oldSharedUserSetting.name : "<nothing>")
- + " to "
- + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
- + "; replacing with new");
- pkgSetting = null;
- }
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Package " + parsedPackage.getPackageName() + " shared user changed from "
+ + (oldSharedUserSetting != null
+ ? oldSharedUserSetting.name : "<nothing>")
+ + " to "
+ + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
+ + "; replacing with new");
+ pkgSetting = null;
}
String[] usesSdkLibraries = null;
@@ -474,8 +464,8 @@ final class ScanPackageUtils {
return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
!createNewPackage /* existingSettingCopied */,
- previousAppId, sdkLibraryInfo, staticSharedLibraryInfo,
- dynamicSharedLibraryInfos);
+ Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo,
+ staticSharedLibraryInfo, dynamicSharedLibraryInfos);
}
/**
diff --git a/services/core/java/com/android/server/pm/ScanResult.java b/services/core/java/com/android/server/pm/ScanResult.java
index f77be1f9b2d3..e2860ca327e7 100644
--- a/services/core/java/com/android/server/pm/ScanResult.java
+++ b/services/core/java/com/android/server/pm/ScanResult.java
@@ -70,7 +70,9 @@ final class ScanResult {
mPkgSetting = pkgSetting;
mChangedAbiCodePath = changedAbiCodePath;
mExistingSettingCopied = existingSettingCopied;
- mPreviousAppId = previousAppId;
+ // Hardcode mPreviousAppId to INVALID_UID (http://b/221088088)
+ // This will disable all migration code paths in PMS and PermMS
+ mPreviousAppId = Process.INVALID_UID;
mSdkSharedLibraryInfo = sdkSharedLibraryInfo;
mStaticSharedLibraryInfo = staticSharedLibraryInfo;
mDynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d3665749a7f8..021c3db35756 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.SharedUidMigration.BEST_EFFORT;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1424,6 +1425,35 @@ public final class Settings implements Watchable, Snappable {
}
}
+ /**
+ * Transparently convert a SharedUserSetting into PackageSettings without changing appId.
+ * The sharedUser passed to this method has to be {@link SharedUserSetting#isSingleUser()}.
+ */
+ void convertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
+ final PackageSetting ps = sharedUser.getPackageSettings().valueAt(0);
+ replaceAppIdLPw(sharedUser.getAppId(), ps);
+
+ // Unlink the SharedUserSetting
+ ps.setSharedUserAppId(INVALID_UID);
+ if (!sharedUser.getDisabledPackageSettings().isEmpty()) {
+ final PackageSetting disabledPs = sharedUser.getDisabledPackageSettings().valueAt(0);
+ disabledPs.setSharedUserAppId(INVALID_UID);
+ }
+ mSharedUsers.remove(sharedUser.getName());
+ }
+
+ /**
+ * Check and convert eligible SharedUserSettings to PackageSettings.
+ */
+ void checkAndConvertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
+ if (!sharedUser.isSingleUser()) return;
+ final AndroidPackage pkg = sharedUser.getPackageSettings().valueAt(0).getPkg();
+ if (pkg != null && pkg.isLeavingSharedUid()
+ && SharedUidMigration.applyStrategy(BEST_EFFORT)) {
+ convertSharedUserSettingsLPw(sharedUser);
+ }
+ }
+
PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
PreferredIntentResolver pir = mPreferredActivities.get(userId);
if (pir == null) {
@@ -4190,10 +4220,11 @@ public final class Settings implements Watchable, Snappable {
// Accumulate all required args and call the installer after mPackages lock
// has been released
final String seInfo = AndroidPackageUtils.getSeInfo(ps.getPkg(), ps);
+ final boolean usesSdk = !ps.getPkg().getUsesSdkLibraries().isEmpty();
final CreateAppDataArgs args = Installer.buildCreateAppDataArgs(
ps.getVolumeUuid(), ps.getPackageName(), userHandle,
StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE,
- ps.getAppId(), seInfo, ps.getPkg().getTargetSdkVersion());
+ ps.getAppId(), seInfo, ps.getPkg().getTargetSdkVersion(), usesSdk);
batch.createAppData(args);
} else {
// Make sure the app is excluded from storage mapping for this user
diff --git a/services/core/java/com/android/server/pm/SharedUidMigration.java b/services/core/java/com/android/server/pm/SharedUidMigration.java
new file mode 100644
index 000000000000..a7d5e9550149
--- /dev/null
+++ b/services/core/java/com/android/server/pm/SharedUidMigration.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.IntDef;
+import android.os.Build;
+import android.os.SystemProperties;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A utility class hosting code configuring shared UID migration behavior.
+ */
+public final class SharedUidMigration {
+
+ /**
+ * The system property key used to configure the shared UID migration strategy.
+ */
+ public static final String PROPERTY_KEY = "persist.debug.pm.shared_uid_migration_strategy";
+
+ /**
+ * Only leave shared UID for newly installed packages.
+ */
+ public static final int NEW_INSTALL_ONLY = 1;
+ /**
+ * Opportunistically migrate any single-package shared UID group.
+ */
+ public static final int BEST_EFFORT = 2;
+ /**
+ * Run appId transitions when the device reboots.
+ */
+ public static final int TRANSITION_AT_BOOT = 3;
+ /**
+ * Run appId transitions as soon as the upgrade is installed.
+ */
+ public static final int LIVE_TRANSITION = 4;
+
+ @IntDef({
+ NEW_INSTALL_ONLY,
+ BEST_EFFORT,
+ TRANSITION_AT_BOOT,
+ LIVE_TRANSITION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Strategy {}
+
+ private static final int DEFAULT = BEST_EFFORT;
+
+ /**
+ * All shared UID migration is disabled.
+ * This is not a strategy that can be set with system properties.
+ * To disable shared UID migration, change {@link #DEFAULT} to this value.
+ */
+ private static final int DISABLED = 0;
+
+ /**
+ * Whether shared UID migration is fully disabled. Disabled means the sharedUserMaxSdkVersion
+ * attribute will be directly ignored in the parsing phase.
+ */
+ @SuppressWarnings("ConstantConditions")
+ public static boolean isDisabled() {
+ return DEFAULT == DISABLED;
+ }
+
+ /**
+ * If the system is userdebug, returns the strategy to use by getting the system property
+ * {@link #PROPERTY_KEY}, or else returns the default strategy enabled in the build.
+ */
+ public static int getCurrentStrategy() {
+ if (!Build.IS_USERDEBUG) {
+ return DEFAULT;
+ }
+
+ final int s = SystemProperties.getInt(PROPERTY_KEY, DEFAULT);
+ // No transition strategies can be used (http://b/221088088)
+ if (s > BEST_EFFORT || s <= DISABLED) {
+ return DEFAULT;
+ }
+ return s;
+ }
+
+ /**
+ * Should the strategy be used based on the current active strategy.
+ */
+ public static boolean applyStrategy(@Strategy int strategy) {
+ return !isDisabled() && getCurrentStrategy() >= strategy;
+ }
+
+ private SharedUidMigration() {}
+}
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 4d0bbc6fe437..23f0de8a5f71 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -221,6 +221,25 @@ public final class SharedUserSetting extends SettingBase implements SharedUserAp
}
/**
+ * A shared user is considered "single user" if there is exactly one single package
+ * currently using it. In the case when that package is also a system app, the APK on
+ * the system partition has to also leave shared UID.
+ */
+ public boolean isSingleUser() {
+ if (mPackages.size() != 1) {
+ return false;
+ }
+ if (mDisabledPackages.size() > 1) {
+ return false;
+ }
+ if (mDisabledPackages.size() == 1) {
+ final AndroidPackage pkg = mDisabledPackages.valueAt(0).getPkg();
+ return pkg != null && pkg.isLeavingSharedUid();
+ }
+ return true;
+ }
+
+ /**
* Determine the targetSdkVersion for a sharedUser and update pkg.applicationInfo.seInfo
* to ensure that all apps within the sharedUser share an SELinux domain. Use the lowest
* targetSdkVersion of all apps within the shared user, which corresponds to the least
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index c76a3fa3ba8f..88a298a756d4 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -15,6 +15,9 @@
"name": "CtsClassloaderSplitsHostTestCases"
},
{
+ "name": "CtsCompilationTestCases"
+ },
+ {
"name": "CtsAppEnumerationTestCases"
},
{
@@ -49,6 +52,9 @@
"options": [
{
"include-filter": "com.google.android.security.gts.PackageVerifierTest"
+ },
+ {
+ "exclude-filter": "com.google.android.security.gts.PackageVerifierTest#testAdbInstall_timeout_allowed"
}
]
},
@@ -108,9 +114,6 @@
},
{
"name": "PackageManagerServiceHostTests"
- },
- {
- "name": "CtsCompilationTestCases"
}
],
"imports": [
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 504769064808..95482d7c7f1a 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -118,8 +118,11 @@ class UserDataPreparer {
flags | StorageManager.FLAG_STORAGE_DE, false);
} else {
try {
- Log.e(TAG, "prepareUserData failed", e);
- RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed");
+ Log.wtf(TAG, "prepareUserData failed for user " + userId, e);
+ if (userId == UserHandle.USER_SYSTEM) {
+ RecoverySystem.rebootPromptAndWipeUserData(mContext,
+ "prepareUserData failed for system user");
+ }
} catch (IOException e2) {
throw new RuntimeException("error rebooting into recovery", e2);
}
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index eb2de6012745..0e6d5e5ed463 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -312,4 +312,12 @@ public abstract class UserManagerInternal {
*/
public abstract void setDefaultCrossProfileIntentFilters(
@UserIdInt int parentUserId, @UserIdInt int profileUserId);
+
+ /**
+ * Returns {@code true} if the system should ignore errors when preparing
+ * the storage directories for the user with ID {@code userId}. This will
+ * return {@code false} for all new users; it will only return {@code true}
+ * for users that already existed on-disk from an older version of Android.
+ */
+ public abstract boolean shouldIgnorePrepareStorageErrors(int userId);
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ad0f9a183c43..a8d24fad2598 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -211,6 +211,8 @@ public class UserManagerService extends IUserManager.Stub {
private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL =
"lastRequestQuietModeEnabledCall";
+ private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS =
+ "ignorePrepareStorageErrors";
private static final String ATTR_KEY = "key";
private static final String ATTR_VALUE_TYPE = "type";
private static final String ATTR_MULTIPLE = "m";
@@ -320,6 +322,14 @@ public class UserManagerService extends IUserManager.Stub {
private long mLastRequestQuietModeEnabledMillis;
+ /**
+ * {@code true} if the system should ignore errors when preparing the
+ * storage directories for this user. This is {@code false} for all new
+ * users; it will only be {@code true} for users that already existed
+ * on-disk from an older version of Android.
+ */
+ private boolean mIgnorePrepareStorageErrors;
+
void setLastRequestQuietModeEnabledMillis(long millis) {
mLastRequestQuietModeEnabledMillis = millis;
}
@@ -328,6 +338,25 @@ public class UserManagerService extends IUserManager.Stub {
return mLastRequestQuietModeEnabledMillis;
}
+ boolean getIgnorePrepareStorageErrors() {
+ return mIgnorePrepareStorageErrors;
+ }
+
+ @SuppressWarnings("AndroidFrameworkCompatChange") // This is not an app-visible API.
+ void setIgnorePrepareStorageErrors() {
+ // This method won't be called for new users. But to fully rule out
+ // the possibility of mIgnorePrepareStorageErrors ever being true
+ // for any user on any device that launched with T or later, we also
+ // explicitly check that DEVICE_INITIAL_SDK_INT is below T before
+ // honoring the request to set mIgnorePrepareStorageErrors to true.
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ mIgnorePrepareStorageErrors = true;
+ return;
+ }
+ Slog.w(LOG_TAG, "Not setting mIgnorePrepareStorageErrors to true"
+ + " since this is a new device");
+ }
+
void clearSeedAccountData() {
seedAccountName = null;
seedAccountType = null;
@@ -1399,21 +1428,28 @@ public class UserManagerService extends IUserManager.Stub {
}
/**
- * Returns a UserInfo object with the name filled in, for Owner, or the original
+ * Returns a UserInfo object with the name filled in, for Owner and Guest, or the original
* if the name is already set.
*/
private UserInfo userWithName(UserInfo orig) {
- if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
- if (DBG_ALLOCATION) {
- final int number = mUser0Allocations.incrementAndGet();
- Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
- }
- UserInfo withName = new UserInfo(orig);
- withName.name = getOwnerName();
- return withName;
- } else {
- return orig;
+ if (orig != null && orig.name == null) {
+ String name = null;
+ if (orig.id == UserHandle.USER_SYSTEM) {
+ if (DBG_ALLOCATION) {
+ final int number = mUser0Allocations.incrementAndGet();
+ Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
+ }
+ name = getOwnerName();
+ } else if (orig.isGuest()) {
+ name = getGuestName();
+ }
+ if (name != null) {
+ final UserInfo withName = new UserInfo(orig);
+ withName.name = name;
+ return withName;
+ }
}
+ return orig;
}
/** Returns whether the given user type is one of the FULL user types. */
@@ -3259,6 +3295,10 @@ public class UserManagerService extends IUserManager.Stub {
return mOwnerName.get();
}
+ private String getGuestName() {
+ return mContext.getString(com.android.internal.R.string.guest_name);
+ }
+
private void invalidateOwnerNameIfNecessary(@NonNull Resources res, boolean forceUpdate) {
final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
if (forceUpdate || (configChanges & mOwnerNameTypedValue.changingConfigurations) != 0) {
@@ -3397,6 +3437,10 @@ public class UserManagerService extends IUserManager.Stub {
serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
}
+ serializer.startTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
+ serializer.text(String.valueOf(userData.getIgnorePrepareStorageErrors()));
+ serializer.endTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
+
serializer.endTag(null, TAG_USER);
serializer.endDocument();
@@ -3506,6 +3550,7 @@ public class UserManagerService extends IUserManager.Stub {
Bundle legacyLocalRestrictions = null;
RestrictionsSet localRestrictions = null;
Bundle globalRestrictions = null;
+ boolean ignorePrepareStorageErrors = true; // default is true for old users
final TypedXmlPullParser parser = Xml.resolvePullParser(is);
int type;
@@ -3584,6 +3629,11 @@ public class UserManagerService extends IUserManager.Stub {
if (type == XmlPullParser.TEXT) {
lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText());
}
+ } else if (TAG_IGNORE_PREPARE_STORAGE_ERRORS.equals(tag)) {
+ type = parser.next();
+ if (type == XmlPullParser.TEXT) {
+ ignorePrepareStorageErrors = Boolean.parseBoolean(parser.getText());
+ }
}
}
}
@@ -3611,6 +3661,9 @@ public class UserManagerService extends IUserManager.Stub {
userData.persistSeedData = persistSeedData;
userData.seedAccountOptions = seedAccountOptions;
userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
+ if (ignorePrepareStorageErrors) {
+ userData.setIgnorePrepareStorageErrors();
+ }
synchronized (mRestrictionsLock) {
if (baseRestrictions != null) {
@@ -5721,6 +5774,9 @@ public class UserManagerService extends IUserManager.Stub {
pw.println();
}
}
+
+ pw.println(" Ignore errors preparing storage: "
+ + userData.getIgnorePrepareStorageErrors());
}
private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) {
@@ -6124,6 +6180,14 @@ public class UserManagerService extends IUserManager.Stub {
UserManagerService.this.setDefaultCrossProfileIntentFilters(
profileUserId, userTypeDetails, restrictions, parentUserId);
}
+
+ @Override
+ public boolean shouldIgnorePrepareStorageErrors(int userId) {
+ synchronized (mUsersLock) {
+ UserData userData = mUsers.get(userId);
+ return userData != null && userData.getIgnorePrepareStorageErrors();
+ }
+ }
}
/**
@@ -6286,7 +6350,8 @@ public class UserManagerService extends IUserManager.Stub {
* {@link SecurityException} if not.
*/
private void verifyCallingPackage(String callingPackage, int callingUid) {
- int packageUid = mPm.getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid));
+ int packageUid = mPm.snapshotComputer()
+ .getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid));
if (packageUid != callingUid) {
throw new SecurityException("Specified package " + callingPackage
+ " does not match the calling uid " + callingUid);
diff --git a/services/core/java/com/android/server/pm/VerificationParams.java b/services/core/java/com/android/server/pm/VerificationParams.java
index 4334cbdce1f2..bc936112649f 100644
--- a/services/core/java/com/android/server/pm/VerificationParams.java
+++ b/services/core/java/com/android/server/pm/VerificationParams.java
@@ -372,9 +372,10 @@ final class VerificationParams extends HandlerParams {
* Determine if we have any installed package verifiers. If we
* do, then we'll defer to them to verify the packages.
*/
+ final Computer snapshot = mPm.snapshotComputer();
final int requiredUid = requiredVerifierPackage == null ? -1
- : mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
- verifierUserId);
+ : snapshot.getPackageUid(requiredVerifierPackage,
+ MATCH_DEBUG_TRIAGED_MISSING, verifierUserId);
verificationState.setRequiredVerifierUid(requiredUid);
final boolean isVerificationEnabled = isVerificationEnabled(pkgLite,
verifierUserId);
@@ -391,8 +392,8 @@ final class VerificationParams extends HandlerParams {
verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Query all live verifiers based on current user state
- final ParceledListSlice<ResolveInfo> receivers = mPm.queryIntentReceivers(verification,
- PACKAGE_MIME_TYPE, 0, verifierUserId);
+ final ParceledListSlice<ResolveInfo> receivers = mPm.queryIntentReceivers(snapshot,
+ verification, PACKAGE_MIME_TYPE, 0, verifierUserId);
if (DEBUG_VERIFY) {
Slog.d(TAG, "Found " + receivers.getList().size() + " verifiers for intent "
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 4714a56d0f14..90842619c31e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -1403,7 +1403,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
} else {
if (ps.getUserStateOrDefault(userId).isInstantApp() && !bp.isInstant()) {
- throw new SecurityException("Cannot grant non-ephemeral permission" + permName
+ throw new SecurityException("Cannot grant non-ephemeral permission " + permName
+ " for package " + packageName);
}
@@ -2554,6 +2554,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
for (int i = 0; i < packagesSize; i++) {
AndroidPackageApi sharedUserPackage =
packages.valueAt(i).getAndroidPackage();
+ if (sharedUserPackage == null) {
+ continue;
+ }
uidRequestedPermissions.addAll(
sharedUserPackage.getRequestedPermissions());
uidImplicitPermissions.addAll(
@@ -3529,8 +3532,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
final Boolean granted =
SystemConfig.getInstance().getOemPermissions(pkg.getPackageName()).get(permission);
if (granted == null) {
- throw new IllegalStateException("OEM permission" + permission + " requested by package "
- + pkg.getPackageName() + " must be explicitly declared granted or not");
+ throw new IllegalStateException("OEM permission " + permission
+ + " requested by package " + pkg.getPackageName()
+ + " must be explicitly declared granted or not");
}
return Boolean.TRUE == granted;
}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index ed1ab01e1d12..3eaca9dddcc4 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -91,6 +91,7 @@ import com.android.internal.R;
import com.android.internal.os.ClassLoaderFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
+import com.android.server.pm.SharedUidMigration;
import com.android.server.pm.permission.CompatibilityPermissionInfo;
import com.android.server.pm.pkg.component.ComponentMutateUtils;
import com.android.server.pm.pkg.component.ComponentParseUtils;
@@ -1047,8 +1048,11 @@ public class ParsingPackageUtils {
}
}
- int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa);
- boolean leaving = (maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT);
+ boolean leaving = false;
+ if (!SharedUidMigration.isDisabled()) {
+ int max = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa);
+ leaving = (max != 0) && (max < Build.VERSION.RESOURCES_SDK_INT);
+ }
return input.success(pkg
.setLeavingSharedUid(leaving)
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index 13218eaf2ded..67aed4506b27 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -256,8 +256,8 @@ public class DomainVerificationService extends SystemService
public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName)
throws NameNotFoundException {
mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
if (pkg == null) {
@@ -315,8 +315,8 @@ public class DomainVerificationService extends SystemService
@NonNull Set<String> domains, int state)
throws NameNotFoundException {
mEnforcer.assertApprovedVerifier(callingUid, mProxy);
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
List<String> verifiedDomains = new ArrayList<>();
GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
@@ -369,8 +369,8 @@ public class DomainVerificationService extends SystemService
ArraySet<String> verifiedDomains = new ArraySet<>();
if (packageName == null) {
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
ArraySet<String> validDomains = new ArraySet<>();
int size = mAttachedPkgStates.size();
@@ -403,8 +403,8 @@ public class DomainVerificationService extends SystemService
}
}
} else {
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
if (pkgState == null) {
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -539,8 +539,8 @@ public class DomainVerificationService extends SystemService
return DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID;
}
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
false /* forAutoVerify */, callingUid, userId, snapshot);
if (result.isError()) {
@@ -578,8 +578,8 @@ public class DomainVerificationService extends SystemService
@NonNull String packageName, boolean enabled, @Nullable ArraySet<String> domains)
throws NameNotFoundException {
mEnforcer.assertInternal(mConnection.getCallingUid());
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
if (pkgState == null) {
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -682,8 +682,8 @@ public class DomainVerificationService extends SystemService
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
}
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
if (pkg == null) {
@@ -1179,8 +1179,8 @@ public class DomainVerificationService extends SystemService
public void printOwnersForPackage(@NonNull IndentingPrintWriter writer,
@Nullable String packageName, @Nullable @UserIdInt Integer userId)
throws NameNotFoundException {
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
if (packageName == null) {
int size = mAttachedPkgStates.size();
for (int index = 0; index < size; index++) {
@@ -1227,8 +1227,8 @@ public class DomainVerificationService extends SystemService
@Override
public void printOwnersForDomains(@NonNull IndentingPrintWriter writer,
@NonNull List<String> domains, @Nullable @UserIdInt Integer userId) {
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
int size = domains.size();
for (int index = 0; index < size; index++) {
printOwnersForDomain(writer, domains.get(index), userId, snapshot);
@@ -1403,8 +1403,8 @@ public class DomainVerificationService extends SystemService
@Override
public void clearDomainVerificationState(@Nullable List<String> packageNames) {
mEnforcer.assertInternal(mConnection.getCallingUid());
+ final Computer snapshot = mConnection.snapshot();
synchronized (mLock) {
- final Computer snapshot = mConnection.snapshot();
if (packageNames == null) {
int size = mAttachedPkgStates.size();
for (int index = 0; index < size; index++) {
diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java
index 68e078c519ba..9213c87f12ec 100644
--- a/services/core/java/com/android/server/policy/KeyCombinationManager.java
+++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java
@@ -48,7 +48,7 @@ public class KeyCombinationManager {
// The rule has been triggered by current keys.
@GuardedBy("mLock")
private TwoKeysCombinationRule mTriggeredRule;
- private final Handler mHandler = new Handler();
+ private final Handler mHandler;
// Keys in a key combination must be pressed within this interval of each other.
private static final long COMBINE_KEY_DELAY_MILLIS = 150;
@@ -93,6 +93,11 @@ public class KeyCombinationManager {
return false;
}
+ // The excessive delay before it dispatching to client.
+ long getKeyInterceptDelayMs() {
+ return COMBINE_KEY_DELAY_MILLIS;
+ }
+
abstract void execute();
abstract void cancel();
@@ -103,7 +108,8 @@ public class KeyCombinationManager {
}
}
- public KeyCombinationManager() {
+ public KeyCombinationManager(Handler handler) {
+ mHandler = handler;
}
void addRule(TwoKeysCombinationRule rule) {
@@ -195,10 +201,18 @@ public class KeyCombinationManager {
*/
long getKeyInterceptTimeout(int keyCode) {
synchronized (mLock) {
- if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) {
- return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS;
+ if (mDownTimes.get(keyCode) == 0) {
+ return 0;
+ }
+ long delayMs = 0;
+ for (final TwoKeysCombinationRule rule : mActiveRules) {
+ if (rule.shouldInterceptKey(keyCode)) {
+ delayMs = Math.max(delayMs, rule.getKeyInterceptDelayMs());
+ }
}
- return 0;
+ // Make sure the delay is less than COMBINE_KEY_DELAY_MILLIS.
+ delayMs = Math.min(delayMs, COMBINE_KEY_DELAY_MILLIS);
+ return mDownTimes.get(keyCode) + delayMs;
}
}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
index 20b7ccd39287..92b9944b74cf 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
@@ -57,6 +57,7 @@ public abstract class PermissionPolicyInternal {
* prompt should be shown if the app targets S-, is currently running in a visible, focused
* task, has the REVIEW_REQUIRED flag set on its implicit notification permission, and has
* created at least one notification channel (even if it has since been deleted).
+ *
* @param packageName The package whose permission is being checked
* @param userId The user for whom the package is being started
* @param taskId The task the notification prompt should be attached to
@@ -66,10 +67,22 @@ public abstract class PermissionPolicyInternal {
/**
* Determine if a particular task is in the proper state to show a system-triggered permission
- * prompt. A prompt can be shown if the task is focused, visible, and running.
+ * prompt. A prompt can be shown if the task is focused, visible, and running and
+ * 1. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER), or
+ * 2. The activity belongs to the same package as the one which launched the task originally,
+ * and the task was started with a launcher intent
+ *
* @param taskInfo The task to be checked
+ * @param currPkg The package of the current top visible activity
+ * @param intent The intent of the current top visible activity
+ */
+ public abstract boolean shouldShowNotificationDialogForTask(@Nullable TaskInfo taskInfo,
+ @Nullable String currPkg, @Nullable Intent intent);
+
+ /**
+ * @return true if an intent will resolve to a permission request dialog activity
*/
- public abstract boolean canShowPermissionPromptForTask(@Nullable TaskInfo taskInfo);
+ public abstract boolean isIntentToPermissionDialog(@NonNull Intent intent);
/**
* @return Whether the policy is initialized for a user.
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index f2ce0d4c49d3..70ef3d364277 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -21,6 +21,8 @@ import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OP_NONE;
+import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS;
+import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
@@ -54,6 +56,8 @@ import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -109,6 +113,7 @@ public final class PermissionPolicyService extends SystemService {
private static final String SYSTEM_PKG = "android";
private static final boolean DEBUG = false;
private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 60000;
+ private static final long ACTIVITY_START_DELAY_MS = 200;
private final Object mLock = new Object();
@@ -149,6 +154,7 @@ public final class PermissionPolicyService extends SystemService {
private List<String> mAppOpPermissions;
private Context mContext;
+ private Handler mHandler;
private PackageManagerInternal mPackageManagerInternal;
private NotificationManagerInternal mNotificationManager;
private final KeyguardManager mKeyguardManager;
@@ -158,6 +164,7 @@ public final class PermissionPolicyService extends SystemService {
super(context);
mContext = context;
+ mHandler = new Handler(Looper.getMainLooper());
mPackageManager = context.getPackageManager();
mKeyguardManager = context.getSystemService(KeyguardManager.class);
LocalServices.addService(PermissionPolicyInternal.class, new Internal());
@@ -1016,7 +1023,7 @@ public final class PermissionPolicyService extends SystemService {
ActivityInterceptorInfo info) {
String action = info.intent.getAction();
ActivityInterceptResult result = null;
- if (!PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)
+ if (!ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)
&& !PackageManager.ACTION_REQUEST_PERMISSIONS.equals(action)) {
return null;
}
@@ -1033,7 +1040,7 @@ public final class PermissionPolicyService extends SystemService {
&& !mContinueNotifGrantMessageUids.contains(info.realCallingUid)) {
return result;
}
- if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)) {
+ if (ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)) {
String otherPkg = info.intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
if (otherPkg == null || (mPackageManager.getPermissionFlags(
POST_NOTIFICATIONS, otherPkg, UserHandle.of(info.userId))
@@ -1052,8 +1059,8 @@ public final class PermissionPolicyService extends SystemService {
public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
ActivityInterceptorInfo info) {
super.onActivityLaunched(taskInfo, activityInfo, info);
- if (!shouldShowNotificationDialogOrClearFlags(info.intent,
- info.checkedOptions)) {
+ if (!shouldShowNotificationDialogOrClearFlags(taskInfo,
+ activityInfo.packageName, info.intent, info.checkedOptions, true)) {
return;
}
UserHandle user = UserHandle.of(taskInfo.userId);
@@ -1085,7 +1092,7 @@ public final class PermissionPolicyService extends SystemService {
return false;
}
- if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(intent.getAction())
+ if (ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(intent.getAction())
&& (callingUid != Process.SYSTEM_UID || !SYSTEM_PKG.equals(callingPackage))) {
return false;
}
@@ -1104,18 +1111,48 @@ public final class PermissionPolicyService extends SystemService {
launchNotificationPermissionRequestDialog(packageName, user, taskId);
}
+ @Override
+ public boolean isIntentToPermissionDialog(@NonNull Intent intent) {
+ return Objects.equals(intent.getPackage(),
+ mPackageManager.getPermissionControllerPackageName())
+ && (Objects.equals(intent.getAction(), ACTION_REQUEST_PERMISSIONS_FOR_OTHER)
+ || Objects.equals(intent.getAction(), ACTION_REQUEST_PERMISSIONS));
+ }
+
+ @Override
+ public boolean shouldShowNotificationDialogForTask(TaskInfo taskInfo, String currPkg,
+ Intent intent) {
+ return shouldShowNotificationDialogOrClearFlags(
+ taskInfo, currPkg, intent, null, false);
+ }
+
/**
- * Determine if we should show a notification dialog, or clear the REVIEW_REQUIRED flag,
- * from a particular package for a particular intent. Returns true if:
+ * Determine if a particular task is in the proper state to show a system-triggered
+ * permission prompt. A prompt can be shown if the task is just starting, or the task is
+ * currently focused, visible, and running, and,
* 1. The isEligibleForLegacyPermissionPrompt ActivityOption is set, or
- * 2. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER)
+ * 2. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER), or
+ * 3. The activity belongs to the same package as the one which launched the task
+ * originally, and the task was started with a launcher intent
+ * @param taskInfo The task to be checked
+ * @param currPkg The package of the current top visible activity
+ * @param intent The intent of the current top visible activity
*/
- private boolean shouldShowNotificationDialogOrClearFlags(Intent intent,
- ActivityOptions options) {
- if ((options != null && options.isEligibleForLegacyPermissionPrompt())) {
- return true;
+ private boolean shouldShowNotificationDialogOrClearFlags(TaskInfo taskInfo, String currPkg,
+ Intent intent, ActivityOptions options, boolean activityStart) {
+ if (intent == null || currPkg == null || taskInfo == null
+ || (!(taskInfo.isFocused && taskInfo.isVisible && taskInfo.isRunning)
+ && !activityStart)) {
+ return false;
}
+ return isLauncherIntent(intent)
+ || (options != null && options.isEligibleForLegacyPermissionPrompt())
+ || (currPkg.equals(taskInfo.baseActivity.getPackageName())
+ && isLauncherIntent(taskInfo.baseIntent));
+ }
+
+ private boolean isLauncherIntent(Intent intent) {
return Intent.ACTION_MAIN.equals(intent.getAction())
&& intent.getCategories() != null
&& (intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)
@@ -1144,14 +1181,15 @@ public final class PermissionPolicyService extends SystemService {
Intent grantPermission = mPackageManager
.buildRequestPermissionsIntent(new String[] { POST_NOTIFICATIONS });
grantPermission.setAction(
- PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER);
+ ACTION_REQUEST_PERMISSIONS_FOR_OTHER);
grantPermission.putExtra(Intent.EXTRA_PACKAGE_NAME, pkgName);
ActivityOptions options = new ActivityOptions(new Bundle());
options.setTaskOverlay(true, false);
options.setLaunchTaskId(taskId);
try {
- mContext.startActivityAsUser(grantPermission, options.toBundle(), user);
+ mHandler.postDelayed(() -> mContext.startActivityAsUser(
+ grantPermission, options.toBundle(), user), ACTIVITY_START_DELAY_MS);
} catch (Exception e) {
Log.e(LOG_TAG, "couldn't start grant permission dialog"
+ "for other package " + pkgName, e);
@@ -1170,12 +1208,6 @@ public final class PermissionPolicyService extends SystemService {
}
}
- @Override
- public boolean canShowPermissionPromptForTask(@Nullable TaskInfo taskInfo) {
- return taskInfo != null && taskInfo.isFocused && taskInfo.isVisible
- && taskInfo.isRunning;
- }
-
/**
* Check if the intent action is removed for the calling package (often based on target SDK
* version). If the action is removed, we'll silently cancel the activity launch.
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cc93d4c1c3ff..e79148d52715 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2124,7 +2124,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void initKeyCombinationRules() {
- mKeyCombinationManager = new KeyCombinationManager();
+ mKeyCombinationManager = new KeyCombinationManager(mHandler);
final boolean screenshotChordEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableScreenshotChord);
@@ -2215,11 +2215,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mBackKeyHandled = true;
interceptAccessibilityGestureTv();
}
-
@Override
void cancel() {
cancelAccessibilityGestureTv();
}
+ @Override
+ long getKeyInterceptDelayMs() {
+ // Use a timeout of 0 to prevent additional latency in processing of
+ // this key. This will potentially cause some unwanted UI actions if the
+ // user does end up triggering the key combination later, but in most
+ // cases, the user will simply hit a single key, and this will allow us
+ // to process it without first waiting to see if the combination is
+ // going to be triggered.
+ return 0;
+ }
});
mKeyCombinationManager.addRule(
@@ -2229,11 +2238,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mBackKeyHandled = true;
interceptBugreportGestureTv();
}
-
@Override
void cancel() {
cancelBugreportGestureTv();
}
+ @Override
+ long getKeyInterceptDelayMs() {
+ return 0;
+ }
});
}
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index dcfb8b5e7b33..a82d4eaa5b28 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManagerInternal;
import android.media.AudioAttributes;
import android.os.FileUtils;
import android.os.Handler;
@@ -525,8 +526,7 @@ public final class ShutdownThread extends Thread {
shutdownTimingLog.traceBegin("ShutdownPackageManager");
metricStarted(METRIC_PM);
- final PackageManagerService pm = (PackageManagerService)
- ServiceManager.getService("package");
+ final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
if (pm != null) {
pm.shutdown();
}
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index c0207f044b83..16592d764e64 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -24,6 +24,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.Environment;
import android.os.FileObserver;
@@ -31,7 +32,6 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.ResultReceiver;
-import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.UserHandle;
@@ -49,6 +49,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.PackageManagerService;
@@ -187,10 +188,10 @@ public class DeviceStorageMonitorService extends SystemService {
// when it's within 150% of the threshold, we try trimming usage
// back to 200% of the threshold.
if (file.getUsableSpace() < (lowBytes * 3) / 2) {
- final PackageManagerService pms = (PackageManagerService) ServiceManager
- .getService("package");
+ final PackageManagerInternal pm =
+ LocalServices.getService(PackageManagerInternal.class);
try {
- pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
+ pm.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
} catch (IOException e) {
Slog.w(TAG, e);
}
@@ -264,10 +265,10 @@ public class DeviceStorageMonitorService extends SystemService {
for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
final File file = vol.getPath();
if (file.getUsableSpace() < file.getTotalSpace() * storageThresholdPercentHigh / 100) {
- final PackageManagerService pms = (PackageManagerService) ServiceManager
- .getService("package");
+ final PackageManagerInternal pm =
+ LocalServices.getService(PackageManagerInternal.class);
try {
- pms.freeAllAppCacheAboveQuota(vol.getFsUuid());
+ pm.freeAllAppCacheAboveQuota(vol.getFsUuid());
} catch (IOException e) {
Slog.w(TAG, e);
}
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index b05b44bcb1d2..77da75118958 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -355,8 +355,10 @@ final class VibrationSettings {
}
}
- if (!shouldVibrateForRingerModeLocked(usage)) {
- return Vibration.Status.IGNORED_FOR_RINGER_MODE;
+ if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
+ if (!shouldVibrateForRingerModeLocked(usage)) {
+ return Vibration.Status.IGNORED_FOR_RINGER_MODE;
+ }
}
}
return null;
@@ -386,12 +388,12 @@ final class VibrationSettings {
* Return {@code true} if the device should vibrate for current ringer mode.
*
* <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
- * for ringtone usage only. All other usages are allowed by this method.
+ * for ringtone and notification usages. All other usages are allowed by this method.
*/
@GuardedBy("mLock")
private boolean shouldVibrateForRingerModeLocked(@VibrationAttributes.Usage int usageHint) {
- if (usageHint != USAGE_RINGTONE) {
- // Only ringtone vibrations are disabled when phone is on silent mode.
+ if ((usageHint != USAGE_RINGTONE) && (usageHint != USAGE_NOTIFICATION)) {
+ // Only ringtone and notification vibrations are disabled when phone is on silent mode.
return true;
}
// If audio manager was not loaded yet then assume most restrictive mode.
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 9ec1079e46cc..1260e5dbc9f7 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -464,10 +464,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
&& shouldCancelVibration(
mCurrentExternalVibration.externalVibration.getVibrationAttributes(),
usageFilter)) {
- endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
mCurrentExternalVibration.externalVibration.mute();
- mCurrentExternalVibration = null;
- setExternalControl(false);
+ endExternalVibrateLocked(Vibration.Status.CANCELLED,
+ /* continueExternalControl= */ false);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1283,7 +1282,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
/** Holder for a {@link ExternalVibration}. */
- private final class ExternalVibrationHolder {
+ private final class ExternalVibrationHolder implements IBinder.DeathRecipient {
public final ExternalVibration externalVibration;
public int scale;
@@ -1308,6 +1307,18 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
mEndTimeDebug = System.currentTimeMillis();
}
+ public void binderDied() {
+ synchronized (mLock) {
+ if (mCurrentExternalVibration != null) {
+ if (DEBUG) {
+ Slog.d(TAG, "External vibration finished because binder died");
+ }
+ endExternalVibrateLocked(Vibration.Status.CANCELLED,
+ /* continueExternalControl= */ false);
+ }
+ }
+ }
+
public Vibration.DebugInfo getDebugInfo() {
return new Vibration.DebugInfo(
mStartTimeDebug, mEndTimeDebug, /* effect= */ null, /* originalEffect= */ null,
@@ -1450,10 +1461,36 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
}
+ /**
+ * Ends the external vibration, and clears related service state.
+ *
+ * @param status the status to end the associated Vibration with
+ * @param continueExternalControl indicates whether external control will continue. If not, the
+ * HAL will have external control turned off.
+ */
+ @GuardedBy("mLock")
+ private void endExternalVibrateLocked(Vibration.Status status,
+ boolean continueExternalControl) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked");
+ try {
+ if (mCurrentExternalVibration == null) {
+ return;
+ }
+ endVibrationLocked(mCurrentExternalVibration, status);
+ mCurrentExternalVibration.externalVibration.unlinkToDeath(
+ mCurrentExternalVibration);
+ mCurrentExternalVibration = null;
+ if (!continueExternalControl) {
+ setExternalControl(false);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+ }
+ }
+
/** Implementation of {@link IExternalVibratorService} to be triggered on external control. */
@VisibleForTesting
final class ExternalVibratorService extends IExternalVibratorService.Stub {
- ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient;
@Override
public int onExternalVibrationStart(ExternalVibration vib) {
@@ -1469,7 +1506,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
return IExternalVibratorService.SCALE_MUTE;
}
- ExternalVibrationHolder cancelingExternalVibration = null;
+ boolean alreadyUnderExternalControl = false;
boolean waitForCompletion = false;
int scale;
synchronized (mLock) {
@@ -1504,13 +1541,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
//
// Note that this doesn't support multiple concurrent external controls, as we
// would need to mute the old one still if it came from a different controller.
+ alreadyUnderExternalControl = true;
mCurrentExternalVibration.externalVibration.mute();
- endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
- cancelingExternalVibration = mCurrentExternalVibration;
+ endExternalVibrateLocked(Vibration.Status.CANCELLED,
+ /* continueExternalControl= */ true);
}
mCurrentExternalVibration = new ExternalVibrationHolder(vib);
- mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient();
- vib.linkToDeath(mCurrentExternalDeathRecipient);
+ vib.linkToDeath(mCurrentExternalVibration);
mCurrentExternalVibration.scale = mVibrationScaler.getExternalVibrationScale(
vib.getVibrationAttributes().getUsage());
scale = mCurrentExternalVibration.scale;
@@ -1520,14 +1557,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
if (!mVibrationThread.waitForThreadIdle(VIBRATION_CANCEL_WAIT_MILLIS)) {
Slog.e(TAG, "Timed out waiting for vibration to cancel");
synchronized (mLock) {
- stopExternalVibrateLocked(Vibration.Status.IGNORED_ERROR_CANCELLING);
+ endExternalVibrateLocked(Vibration.Status.IGNORED_ERROR_CANCELLING,
+ /* continueExternalControl= */ false);
}
return IExternalVibratorService.SCALE_MUTE;
}
}
- if (cancelingExternalVibration == null) {
- // We only need to set external control if it was not already set by another
- // external vibration.
+ if (!alreadyUnderExternalControl) {
if (DEBUG) {
Slog.d(TAG, "Vibrator going under external control.");
}
@@ -1547,29 +1583,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
if (DEBUG) {
Slog.e(TAG, "Stopping external vibration" + vib);
}
- stopExternalVibrateLocked(Vibration.Status.FINISHED);
+ endExternalVibrateLocked(Vibration.Status.FINISHED,
+ /* continueExternalControl= */ false);
}
}
}
- @GuardedBy("mLock")
- private void stopExternalVibrateLocked(Vibration.Status status) {
- Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "stopExternalVibrateLocked");
- try {
- if (mCurrentExternalVibration == null) {
- return;
- }
- endVibrationLocked(mCurrentExternalVibration, status);
- mCurrentExternalVibration.externalVibration.unlinkToDeath(
- mCurrentExternalDeathRecipient);
- mCurrentExternalDeathRecipient = null;
- mCurrentExternalVibration = null;
- setExternalControl(false);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
- }
- }
-
private boolean hasExternalControlCapability() {
for (int i = 0; i < mVibrators.size(); i++) {
if (mVibrators.valueAt(i).hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
@@ -1578,19 +1597,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
return false;
}
-
- private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient {
- public void binderDied() {
- synchronized (mLock) {
- if (mCurrentExternalVibration != null) {
- if (DEBUG) {
- Slog.d(TAG, "External vibration finished because binder died");
- }
- stopExternalVibrateLocked(Vibration.Status.CANCELLED);
- }
- }
- }
- }
}
/** Provide limited functionality from {@link VibratorManagerService} as shell commands. */
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index f9689a8a2bca..d4648a4f313c 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -27,6 +27,7 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.os.Handler;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Looper;
import android.os.Message;
import android.util.Slog;
@@ -153,7 +154,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
final List<InputWindowHandle> tempVisibleWindows = new ArrayList<>();
for (InputWindowHandle window : windowHandles) {
- if (window.visible && window.getWindow() != null) {
+ final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
+ if (visible && window.getWindow() != null) {
tempVisibleWindows.add(window);
}
}
@@ -641,7 +643,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
final RecentsAnimationController controller = service.getRecentsAnimationController();
instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
&& controller.shouldIgnoreForAccessibility(windowState);
- instance.mIsTrustedOverlay = inputWindowHandle.trustedOverlay;
+ instance.mIsTrustedOverlay =
+ (inputWindowHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
// TODO (b/199358388) : gets the letterbox bounds of the window from other way.
if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
index 06c58baee1f9..1d65cbb70ffe 100644
--- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
+++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
@@ -58,6 +58,7 @@ public abstract class ActivityInterceptorCallback {
@IntDef(suffix = { "_ORDERED_ID" }, value = {
FIRST_ORDERED_ID,
PERMISSION_POLICY_ORDERED_ID,
+ INTENT_RESOLVER_ORDERED_ID,
VIRTUAL_DEVICE_SERVICE_ORDERED_ID,
LAST_ORDERED_ID // Update this when adding new ids
})
@@ -75,6 +76,11 @@ public abstract class ActivityInterceptorCallback {
public static final int PERMISSION_POLICY_ORDERED_ID = 1;
/**
+ * The identifier for {@link com.android.server.pm.IntentResolverInterceptor}.
+ */
+ public static final int INTENT_RESOLVER_ORDERED_ID = 2;
+
+ /**
* The identifier for {@link com.android.server.companion.virtual.VirtualDeviceManagerService}
* interceptor.
*/
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e66f309d2ccc..1c93abd60752 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -278,6 +278,7 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.gui.DropInputMode;
import android.hardware.HardwareBuffer;
import android.net.Uri;
import android.os.Binder;
@@ -782,6 +783,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean startingDisplayed;
boolean startingMoved;
+ /** The last set {@link DropInputMode} for this activity surface. */
+ @DropInputMode
+ private int mLastDropInputMode = DropInputMode.NONE;
+
/**
* If it is non-null, it requires all activities who have the same starting data to be drawn
* to remove the starting window.
@@ -1548,6 +1553,60 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
rootTask.setHasBeenVisible(true);
}
}
+
+ // Update the input mode if the embedded mode is changed.
+ updateUntrustedEmbeddingInputProtection();
+ }
+
+ @Override
+ void setSurfaceControl(SurfaceControl sc) {
+ super.setSurfaceControl(sc);
+ if (sc != null) {
+ mLastDropInputMode = DropInputMode.NONE;
+ updateUntrustedEmbeddingInputProtection();
+ }
+ }
+
+ /**
+ * Sets to drop input when obscured to activity if it is embedded in untrusted mode.
+ *
+ * Although the untrusted embedded activity should be invisible when behind other overlay,
+ * theoretically even if this activity is the top most, app can still move surface of activity
+ * below it to the top. As a result, we want to update the input mode to drop when obscured for
+ * all untrusted activities.
+ */
+ private void updateUntrustedEmbeddingInputProtection() {
+ final SurfaceControl sc = getSurfaceControl();
+ if (sc == null) {
+ return;
+ }
+ if (isEmbeddedInUntrustedMode()) {
+ // Set drop input to OBSCURED when untrusted embedded.
+ setDropInputMode(DropInputMode.OBSCURED);
+ } else {
+ // Reset drop input mode when this activity is not embedded in untrusted mode.
+ setDropInputMode(DropInputMode.NONE);
+ }
+ }
+
+ @VisibleForTesting
+ void setDropInputMode(@DropInputMode int mode) {
+ if (mLastDropInputMode != mode && getSurfaceControl() != null) {
+ mLastDropInputMode = mode;
+ mWmService.mTransactionFactory.get()
+ .setDropInputMode(getSurfaceControl(), mode)
+ .apply();
+ }
+ }
+
+ private boolean isEmbeddedInUntrustedMode() {
+ final TaskFragment organizedTaskFragment = getOrganizedTaskFragment();
+ if (organizedTaskFragment == null) {
+ // Not embedded.
+ return false;
+ }
+ // Check if trusted.
+ return !organizedTaskFragment.isAllowedToEmbedActivityInTrustedMode(this);
}
void updateAnimatingActivityRegistry() {
@@ -2452,7 +2511,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// either way, abort and reset the sequence.
if (parcelable == null
|| mTransferringSplashScreenState != TRANSFER_SPLASH_SCREEN_COPYING
- || mStartingWindow == null) {
+ || mStartingWindow == null
+ || finishing) {
if (parcelable != null) {
parcelable.clearIfNeeded();
}
@@ -3642,6 +3702,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return;
}
finishing = true;
+
+ // Transfer the launch cookie to the next running activity above this in the same task.
+ if (mLaunchCookie != null && mState != RESUMED && task != null && !task.mInRemoveTask
+ && !task.isClearingToReuseTask()) {
+ final ActivityRecord nextCookieTarget = task.getActivity(
+ // Intend to only associate the same app by checking uid.
+ r -> r.mLaunchCookie == null && !r.finishing && r.isUid(getUid()),
+ this, false /* includeBoundary */, false /* traverseTopToBottom */);
+ if (nextCookieTarget != null) {
+ nextCookieTarget.mLaunchCookie = mLaunchCookie;
+ mLaunchCookie = null;
+ }
+ }
+
final TaskFragment taskFragment = getTaskFragment();
if (taskFragment != null) {
final Task task = taskFragment.getTask();
@@ -5428,6 +5502,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
+ // Untrusted embedded activity can be visible only if there is no other overlay window.
+ if (hasOverlayOverUntrustedModeEmbedded()) {
+ return false;
+ }
+
// Check if the activity is on a sleeping display, canTurnScreenOn will also check
// keyguard visibility
if (mDisplayContent.isSleeping()) {
@@ -5437,6 +5516,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
+ /**
+ * Checks if there are any activities or other containers that belong to the same task on top of
+ * this activity when embedded in untrusted mode.
+ */
+ boolean hasOverlayOverUntrustedModeEmbedded() {
+ if (!isEmbeddedInUntrustedMode() || getRootTask() == null) {
+ // The activity is not embedded in untrusted mode.
+ return false;
+ }
+
+ // Check if there are any activities with different UID over the activity that is embedded
+ // in untrusted mode. Traverse bottom to top with boundary so that it will only check
+ // activities above this activity.
+ final ActivityRecord differentUidOverlayActivity = getRootTask().getActivity(
+ a -> a.getUid() != getUid(), this /* boundary */, false /* includeBoundary */,
+ false /* traverseTopToBottom */);
+ return differentUidOverlayActivity != null;
+ }
+
void updateVisibilityIgnoringKeyguard(boolean behindFullscreenActivity) {
visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
&& showToCurrentUser();
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index 19d5449254ff..8622bd32fc68 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.InputConstants;
import android.os.Looper;
import android.os.Process;
@@ -111,13 +112,12 @@ class ActivityRecordInputSink {
mActivityRecord.getDisplayId());
inputWindowHandle.replaceTouchableRegionWithCrop = true;
inputWindowHandle.name = mName;
+ inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
inputWindowHandle.ownerUid = Process.myUid();
inputWindowHandle.ownerPid = Process.myPid();
- inputWindowHandle.layoutParamsFlags =
- WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
inputWindowHandle.dispatchingTimeoutMillis =
InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+ inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
return inputWindowHandle;
}
@@ -169,5 +169,4 @@ class ActivityRecordInputSink {
finishInputEvent(event, true);
}
}
-
}
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index c5fcd12efa78..cdeb86c3ee77 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -355,10 +355,10 @@ class ActivityStartInterceptor {
* @return The intercepting intent if needed.
*/
private Intent interceptWithConfirmCredentialsIfNeeded(ActivityInfo aInfo, int userId) {
- if (!mService.mAmInternal.shouldConfirmCredentials(userId)) {
+ if ((aInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0
+ || !mService.mAmInternal.shouldConfirmCredentials(userId)) {
return null;
}
- // TODO(b/28935539): should allow certain activities to bypass work challenge
final IntentSender target = createIntentSenderForOriginalIntent(mCallingUid,
FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE);
final KeyguardManager km = (KeyguardManager) mServiceContext
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index fd2afd47bec4..ac121a13f308 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1816,7 +1816,8 @@ class ActivityStarter {
}
if (mTargetRootTask == null) {
- mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
+ mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
+ mOptions);
}
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
@@ -1925,7 +1926,7 @@ class ActivityStarter {
} else if (mInTask != null) {
return mInTask;
} else {
- final Task rootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, null /* task */,
+ final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */,
mOptions);
final ActivityRecord top = rootTask.getTopNonFinishingActivity();
if (top != null) {
@@ -2233,7 +2234,7 @@ class ActivityStarter {
if (targetTask.getRootTask() == null) {
// Target root task got cleared when we all activities were removed above.
// Go ahead and reset it.
- mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags,
+ mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags,
null /* task */, mOptions);
mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
(mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
@@ -2695,10 +2696,11 @@ class ActivityStarter {
// launched into the same root task.
mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask);
} else {
- final Task launchRootTask =
- getLaunchRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions);
+ final Task rootTask =
+ getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions);
+ // TODO(b/184806710): #getOrCreateRootTask should never return null?
mTargetRootTask =
- launchRootTask != null ? launchRootTask : intentActivity.getRootTask();
+ rootTask != null ? rootTask : intentActivity.getRootTask();
}
}
@@ -2929,7 +2931,7 @@ class ActivityStarter {
return launchFlags;
}
- private Task getLaunchRootTask(ActivityRecord r, int launchFlags, Task task,
+ private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task,
ActivityOptions aOptions) {
// We are reusing a task, keep the root task!
if (mReuseTask != null) {
@@ -2938,7 +2940,7 @@ class ActivityStarter {
final boolean onTop =
(aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
- return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
+ return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, mSourceRootTask, onTop,
mLaunchParams, launchFlags);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index cecfccd1f836..01dfb91d12be 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -680,4 +680,15 @@ public abstract class ActivityTaskManagerInternal {
/** Get the app tasks for a package */
public abstract List<ActivityManager.AppTask> getAppTasks(String pkgName, int uid);
+
+ /**
+ * Determine if there exists a task which meets the criteria set by the PermissionPolicyService
+ * to show a system-owned permission dialog over, for a given package
+ * @see PermissionPolicyInternal.shouldShowNotificationDialogForTask
+ *
+ * @param pkgName The package whose activity must be top
+ * @param uid The uid that must have a top activity
+ * @return a task ID if a valid task ID is found. Otherwise, return INVALID_TASK_ID
+ */
+ public abstract int getTaskToShowPermissionDialogOn(String pkgName, int uid);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index bfccdf97c680..6d8b3b1d63dd 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6754,5 +6754,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
return tasks;
}
+
+ @Override
+ public int getTaskToShowPermissionDialogOn(String pkgName, int uid) {
+ synchronized (ActivityTaskManagerService.this.mGlobalLock) {
+ return ActivityTaskManagerService.this.mRootWindowContainer
+ .getTaskToShowPermissionDialogOn(pkgName, uid);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 5573f161d1c1..64f426187fd2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -954,7 +954,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// This is the first time we failed -- restart process and
// retry.
r.launchFailed = true;
- proc.removeActivity(r, true /* keepAssociation */);
+ r.detachFromProcess();
throw e;
}
} finally {
@@ -1046,6 +1046,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
+ // Remove the process record so it won't be considered as alive.
+ mService.mProcessNames.remove(wpc.mName, wpc.mUid);
+ mService.mProcessMap.remove(wpc.getPid());
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
@@ -1436,20 +1439,20 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final Rect bounds = options.getLaunchBounds();
task.setBounds(bounds);
- Task launchRootTask =
- mRootWindowContainer.getLaunchRootTask(null, options, task, ON_TOP);
+ Task targetRootTask =
+ mRootWindowContainer.getOrCreateRootTask(null, options, task, ON_TOP);
- if (launchRootTask != currentRootTask) {
- moveHomeRootTaskToFrontIfNeeded(flags, launchRootTask.getDisplayArea(), reason);
- task.reparent(launchRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
+ if (targetRootTask != currentRootTask) {
+ moveHomeRootTaskToFrontIfNeeded(flags, targetRootTask.getDisplayArea(), reason);
+ task.reparent(targetRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
!ANIMATE, DEFER_RESUME, reason);
- currentRootTask = launchRootTask;
+ currentRootTask = targetRootTask;
reparented = true;
// task.reparent() should already placed the task on top,
// still need moveTaskToFrontLocked() below for any transition settings.
}
- if (launchRootTask.shouldResizeRootTaskWithLaunchBounds()) {
- launchRootTask.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME);
+ if (targetRootTask.shouldResizeRootTaskWithLaunchBounds()) {
+ targetRootTask.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME);
} else {
// WM resizeTask must be done after the task is moved to the correct stack,
// because Task's setBounds() also updates dim layer's bounds, but that has
@@ -1693,7 +1696,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
*/
boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
final Task rootTask =
- mRootWindowContainer.getLaunchRootTask(null, aOptions, task, onTop);
+ mRootWindowContainer.getOrCreateRootTask(null, aOptions, task, onTop);
final WindowContainer parent = task.getParent();
if (parent == rootTask || task == rootTask) {
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 9e889ad11b8e..220d9ec8febb 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -329,8 +329,12 @@ class AsyncRotationController extends FadeAnimationController implements Consume
void hideImmediately(WindowToken windowToken) {
final boolean original = mHideImmediately;
mHideImmediately = true;
+ final Operation op = new Operation(Operation.ACTION_FADE);
+ mTargetWindowTokens.put(windowToken, op);
fadeWindowToken(false /* show */, windowToken, ANIMATION_TYPE_FIXED_TRANSFORM);
+ op.mLeash = windowToken.getAnimationLeash();
mHideImmediately = original;
+ if (DEBUG) Slog.d(TAG, "hideImmediately " + windowToken.getTopChild());
}
/** Returns {@code true} if the window will rotate independently. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e80d323c3e36..d1b9a7895058 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -131,6 +131,7 @@ import static com.android.server.wm.DisplayContentProto.SLEEP_TOKENS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_CONTENT;
@@ -414,6 +415,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final Region mSystemGestureExclusionUnrestricted = new Region();
private int mSystemGestureExclusionLimit;
+ private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
+ private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
+
/**
* For default display it contains real metrics, empty for others.
* @see WindowManagerService#createWatermark()
@@ -624,9 +628,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@VisibleForTesting
SurfaceControl mInputMethodSurfaceParent;
- /** The screenshot IME surface to place on the task while transitioning to the next task. */
- SurfaceControl mImeScreenshot;
-
private final PointerEventDispatcher mPointerEventDispatcher;
private final InsetsStateController mInsetsStateController;
@@ -3351,7 +3352,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
pw.println(mSystemGestureExclusion);
}
- final List<Rect> keepClearAreas = getKeepClearAreas();
+ final Set<Rect> keepClearAreas = getKeepClearAreas();
if (!keepClearAreas.isEmpty()) {
pw.println();
pw.print(" keepClearAreas=");
@@ -3971,10 +3972,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// If the IME target is the input target, before it changes, prepare the IME screenshot
// for the last IME target when its task is applying app transition. This is for the
// better IME transition to keep IME visibility when transitioning to the next task.
- if (mImeLayeringTarget != null && mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
- ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
- && mImeLayeringTarget == mImeInputTarget) {
- attachAndShowImeScreenshotOnTarget();
+ if (mImeLayeringTarget != null && mImeLayeringTarget == mImeInputTarget) {
+ boolean nonAppImeTargetAnimatingExit = mImeLayeringTarget.mAnimatingExit
+ && mImeLayeringTarget.mAttrs.type != TYPE_BASE_APPLICATION
+ && mImeLayeringTarget.isSelfAnimating(0, ANIMATION_TYPE_WINDOW_ANIMATION);
+ if (mImeLayeringTarget.inAppOrRecentsTransition() || nonAppImeTargetAnimatingExit) {
+ showImeScreenshot();
+ }
}
ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target);
@@ -4022,71 +4026,129 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mImeControlTarget = target;
}
- @VisibleForTesting
- void attachAndShowImeScreenshotOnTarget() {
- // No need to attach screenshot if the IME target not exists or screen is off.
- if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
- return;
+ // ========== Begin of ImeScreenshot stuff ==========
+ /** The screenshot IME surface to place on the task while transitioning to the next task. */
+ ImeScreenshot mImeScreenshot;
+
+ static final class ImeScreenshot {
+ private WindowState mImeTarget;
+ private SurfaceControl.Builder mSurfaceBuilder;
+ private SurfaceControl mImeSurface;
+
+ ImeScreenshot(SurfaceControl.Builder surfaceBuilder, @NonNull WindowState imeTarget) {
+ mSurfaceBuilder = surfaceBuilder;
+ mImeTarget = imeTarget;
}
- final SurfaceControl.Transaction t = getPendingTransaction();
- // Prepare IME screenshot for the target if it allows to attach into.
- if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
- final Task task = mImeLayeringTarget.getTask();
+ WindowState getImeTarget() {
+ return mImeTarget;
+ }
+
+ private SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer b,
+ Transaction t) {
+ final HardwareBuffer buffer = b.getHardwareBuffer();
+ if (DEBUG_INPUT_METHOD) {
+ Slog.d(TAG, "create IME snapshot for "
+ + mImeTarget + ", buff width=" + buffer.getWidth()
+ + ", height=" + buffer.getHeight());
+ }
+ final WindowState imeWindow = mImeTarget.getDisplayContent().mInputMethodWindow;
+ final ActivityRecord activity = mImeTarget.mActivityRecord;
+ final SurfaceControl imeParent = mImeTarget.mAttrs.type == TYPE_BASE_APPLICATION
+ ? activity.getSurfaceControl()
+ : mImeTarget.getSurfaceControl();
+ final SurfaceControl imeSurface = mSurfaceBuilder
+ .setName("IME-snapshot-surface")
+ .setBLASTLayer()
+ .setFormat(buffer.getFormat())
+ // Attaching IME snapshot to the associated IME layering target on the
+ // activity when:
+ // - The target is activity main window: attaching on top of the activity.
+ // - The target is non-activity main window (e.g. activity overlay or
+ // dialog-themed activity): attaching on top of the target since the layer has
+ // already above the activity.
+ .setParent(imeParent)
+ .setCallsite("DisplayContent.attachAndShowImeScreenshotOnTarget")
+ .build();
+ // Make IME snapshot as trusted overlay
+ InputMonitor.setTrustedOverlayInputInfo(imeSurface, t, imeWindow.getDisplayId(),
+ "IME-snapshot-surface");
+ t.setBuffer(imeSurface, buffer);
+ t.setColorSpace(activity.mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
+ t.setLayer(imeSurface, 1);
+
+ final Point surfacePosition = new Point(
+ imeWindow.getFrame().left - mImeTarget.getFrame().left,
+ imeWindow.getFrame().top - mImeTarget.getFrame().top);
+ if (imeParent == activity.getSurfaceControl()) {
+ t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
+ } else {
+ surfacePosition.offset(mImeTarget.mAttrs.surfaceInsets.left,
+ mImeTarget.mAttrs.surfaceInsets.top);
+ t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
+ }
+ return imeSurface;
+ }
+
+ private void removeImeSurface(Transaction t) {
+ if (mImeSurface != null) {
+ if (DEBUG_INPUT_METHOD) Slog.d(TAG, "remove IME snapshot");
+ t.remove(mImeSurface);
+ mImeSurface = null;
+ }
+ }
+
+ void attachAndShow(Transaction t) {
+ final DisplayContent dc = mImeTarget.getDisplayContent();
+ // Prepare IME screenshot for the target if it allows to attach into.
+ final Task task = mImeTarget.getTask();
// Re-new the IME screenshot when it does not exist or the size changed.
- final boolean renewImeSurface = mImeScreenshot == null
- || mImeScreenshot.getWidth() != mInputMethodWindow.getFrame().width()
- || mImeScreenshot.getHeight() != mInputMethodWindow.getFrame().height();
+ final boolean renewImeSurface = mImeSurface == null
+ || mImeSurface.getWidth() != dc.mInputMethodWindow.getFrame().width()
+ || mImeSurface.getHeight() != dc.mInputMethodWindow.getFrame().height();
if (task != null && !task.isActivityTypeHomeOrRecents()) {
SurfaceControl.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
- ? mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
+ ? dc.mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
: null;
if (imeBuffer != null) {
// Remove the last IME surface when the surface needs to renew.
- removeImeSurfaceImmediately();
- mImeScreenshot = createImeSurface(imeBuffer, t);
+ removeImeSurface(t);
+ mImeSurface = createImeSurface(imeBuffer, t);
+ }
+ }
+ final boolean isValidSnapshot = mImeSurface != null && mImeSurface.isValid();
+ // Showing the IME screenshot if the target has already in app transition stage.
+ // Note that if the current IME insets is not showing, no need to show IME screenshot
+ // to reflect the true IME insets visibility and the app task layout as possible.
+ if (isValidSnapshot
+ && dc.getInsetsStateController().getImeSourceProvider().isImeShowing()) {
+ if (DEBUG_INPUT_METHOD) {
+ Slog.d(TAG, "show IME snapshot, ime target=" + mImeTarget);
}
+ t.show(mImeSurface);
+ } else if (!isValidSnapshot) {
+ removeImeSurface(t);
}
}
- final boolean isValidSnapshot = mImeScreenshot != null && mImeScreenshot.isValid();
- // Showing the IME screenshot if the target has already in app transition stage.
- // Note that if the current IME insets is not showing, no need to show IME screenshot
- // to reflect the true IME insets visibility and the app task layout as possible.
- if (isValidSnapshot && getInsetsStateController().getImeSourceProvider().isImeShowing()) {
- if (DEBUG_INPUT_METHOD) {
- Slog.d(TAG, "show IME snapshot, ime target=" + mImeLayeringTarget);
- }
- t.show(mImeScreenshot);
- } else if (!isValidSnapshot) {
- removeImeSurfaceImmediately();
+ void detach(Transaction t) {
+ removeImeSurface(t);
}
}
- @VisibleForTesting
- SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer imeBuffer,
- Transaction t) {
- final HardwareBuffer buffer = imeBuffer.getHardwareBuffer();
- if (DEBUG_INPUT_METHOD) Slog.d(TAG, "create IME snapshot for "
- + mImeLayeringTarget + ", buff width=" + buffer.getWidth()
- + ", height=" + buffer.getHeight());
- final ActivityRecord activity = mImeLayeringTarget.mActivityRecord;
- final SurfaceControl imeSurface = mWmService.mSurfaceControlFactory.apply(null)
- .setName("IME-snapshot-surface")
- .setBLASTLayer()
- .setFormat(buffer.getFormat())
- .setParent(activity.getSurfaceControl())
- .setCallsite("DisplayContent.attachAndShowImeScreenshotOnTarget")
- .build();
- // Make IME snapshot as trusted overlay
- InputMonitor.setTrustedOverlayInputInfo(imeSurface, t, getDisplayId(),
- "IME-snapshot-surface");
- t.setBuffer(imeSurface, buffer);
- t.setColorSpace(mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
- t.setLayer(imeSurface, 1);
- t.setPosition(imeSurface, mInputMethodWindow.getDisplayFrame().left,
- mInputMethodWindow.getDisplayFrame().top);
- return imeSurface;
+ private void attachAndShowImeScreenshotOnTarget() {
+ // No need to attach screenshot if the IME target not exists or screen is off.
+ if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
+ return;
+ }
+
+ final SurfaceControl.Transaction t = getPendingTransaction();
+ // Prepare IME screenshot for the target if it allows to attach into.
+ if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
+ mImeScreenshot = new ImeScreenshot(
+ mWmService.mSurfaceControlFactory.apply(null), mImeLayeringTarget);
+ mImeScreenshot.attachAndShow(t);
+ }
}
/**
@@ -4108,8 +4170,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void removeImeScreenshotIfPossible() {
if (mImeLayeringTarget == null
|| mImeLayeringTarget.mAttrs.type != TYPE_APPLICATION_STARTING
- && !mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
- ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)) {
+ && !mImeLayeringTarget.inAppOrRecentsTransition()) {
removeImeSurfaceImmediately();
}
}
@@ -4117,11 +4178,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/** Removes the IME screenshot immediately. */
void removeImeSurfaceImmediately() {
if (mImeScreenshot != null) {
- if (DEBUG_INPUT_METHOD) Slog.d(TAG, "remove IME snapshot");
- getSyncTransaction().remove(mImeScreenshot);
+ mImeScreenshot.detach(getSyncTransaction());
mImeScreenshot = null;
}
}
+ // ========== End of ImeScreenshot stuff ==========
/**
* The IME input target is the window which receives input from IME. It is also a candidate
@@ -4430,7 +4491,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* hierarchy.
*/
void onWindowAnimationFinished(@NonNull WindowContainer wc, int type) {
- if (type == ANIMATION_TYPE_APP_TRANSITION || type == ANIMATION_TYPE_RECENTS) {
+ if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
+ || wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
+ && (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
removeImeSurfaceImmediately();
}
}
@@ -5453,11 +5516,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
void updateKeepClearAreas() {
- final List<Rect> restrictedKeepClearAreas = new ArrayList();
- final List<Rect> unrestrictedKeepClearAreas = new ArrayList();
+ final Set<Rect> restrictedKeepClearAreas = new ArraySet<>();
+ final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>();
getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas);
- mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged(
- this, restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+
+ if (!mRestrictedKeepClearAreas.equals(restrictedKeepClearAreas)
+ || !mUnrestrictedKeepClearAreas.equals(unrestrictedKeepClearAreas)) {
+ mRestrictedKeepClearAreas = restrictedKeepClearAreas;
+ mUnrestrictedKeepClearAreas = unrestrictedKeepClearAreas;
+ mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged(
+ this, restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+ }
}
/**
@@ -5469,7 +5538,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* For context on restricted vs unrestricted keep-clear areas, see
* {@link android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS}.
*/
- void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) {
+ void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) {
final Matrix tmpMatrix = new Matrix();
final float[] tmpFloat9 = new float[9];
forAllWindows(w -> {
@@ -5486,8 +5555,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/**
* Returns all keep-clear areas from visible, relevant windows on this display.
*/
- ArrayList<Rect> getKeepClearAreas() {
- final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>();
+ Set<Rect> getKeepClearAreas() {
+ final Set<Rect> keepClearAreas = new ArraySet<>();
getKeepClearAreas(keepClearAreas, keepClearAreas);
return keepClearAreas;
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index e18d5396831a..fa7a99d55896 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -23,7 +23,8 @@ import android.os.RemoteException;
import android.util.IntArray;
import android.view.IDisplayWindowListener;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
/**
* Manages dispatch of relevant hierarchy changes to interested listeners. Listeners are assumed
@@ -120,13 +121,13 @@ class DisplayWindowListenerController {
mDisplayListeners.finishBroadcast();
}
- void dispatchKeepClearAreasChanged(DisplayContent display, List<Rect> restricted,
- List<Rect> unrestricted) {
+ void dispatchKeepClearAreasChanged(DisplayContent display, Set<Rect> restricted,
+ Set<Rect> unrestricted) {
int count = mDisplayListeners.beginBroadcast();
for (int i = 0; i < count; ++i) {
try {
- mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged(
- display.mDisplayId, restricted, unrestricted);
+ mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged(display.mDisplayId,
+ new ArrayList<>(restricted), new ArrayList<>(unrestricted));
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 00380bb6e84e..c47d778c60bc 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -44,6 +44,7 @@ import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -127,7 +128,7 @@ class DragState {
@Nullable private ValueAnimator mAnimator;
private final Interpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
- private Point mDisplaySize = new Point();
+ private final Point mDisplaySize = new Point();
// A surface used to catch input events for the drag-and-drop operation.
SurfaceControl mInputSurface;
@@ -160,8 +161,7 @@ class DragState {
private void showInputSurface() {
if (mInputSurface == null) {
- mInputSurface = mService.makeSurfaceBuilder(
- mService.mRoot.getDisplayContent(mDisplayContent.getDisplayId()).getSession())
+ mInputSurface = mService.makeSurfaceBuilder(mDisplayContent.getSession())
.setContainerLayer()
.setName("Drag and Drop Input Consumer")
.setCallsite("DragState.showInputSurface")
@@ -174,17 +174,18 @@ class DragState {
return;
}
- mTransaction.show(mInputSurface);
- mTransaction.setInputWindowInfo(mInputSurface, h);
- mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
-
+ // Crop the input surface to the display size.
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
- mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
+
+ mTransaction.show(mInputSurface)
+ .setInputWindowInfo(mInputSurface, h)
+ .setLayer(mInputSurface, Integer.MAX_VALUE)
+ .setCrop(mInputSurface, mTmpClipRect);
// syncInputWindows here to ensure the input window info is sent before the
// transferTouchFocus is called.
- mTransaction.syncInputWindows();
- mTransaction.apply(true);
+ mTransaction.syncInputWindows()
+ .apply(true /*sync*/);
}
/**
@@ -361,29 +362,20 @@ class DragState {
display.getDisplayId());
mDragWindowHandle.name = "drag";
mDragWindowHandle.token = mClientChannel.getToken();
- mDragWindowHandle.layoutParamsFlags = 0;
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mDragWindowHandle.visible = true;
- // Allows the system to consume keys when dragging is active. This can also be used to
- // modify the drag state on key press. Example, cancel drag on escape key.
- mDragWindowHandle.focusable = true;
- mDragWindowHandle.hasWallpaper = false;
- mDragWindowHandle.paused = false;
mDragWindowHandle.ownerPid = Process.myPid();
mDragWindowHandle.ownerUid = Process.myUid();
- mDragWindowHandle.inputFeatures = 0;
mDragWindowHandle.scaleFactor = 1.0f;
+ // Keep the default behavior of this window to be focusable, which allows the system
+ // to consume keys when dragging is active. This can also be used to modify the drag
+ // state on key press. For example, cancel drag on escape key.
+ mDragWindowHandle.inputConfig = InputConfig.PREVENT_SPLITTING;
+
// The drag window cannot receive new touches.
mDragWindowHandle.touchableRegion.setEmpty();
- // The drag window covers the entire display
- mDragWindowHandle.frameLeft = 0;
- mDragWindowHandle.frameTop = 0;
- mDragWindowHandle.frameRight = mDisplaySize.x;
- mDragWindowHandle.frameBottom = mDisplaySize.y;
-
// Pause rotations before a drag.
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag");
mService.mRoot.forAllDisplays(dc -> {
diff --git a/services/core/java/com/android/server/wm/InputConfigAdapter.java b/services/core/java/com/android/server/wm/InputConfigAdapter.java
new file mode 100644
index 000000000000..2dcde4ee2ba8
--- /dev/null
+++ b/services/core/java/com/android/server/wm/InputConfigAdapter.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.os.InputConfig;
+import android.view.InputWindowHandle.InputConfigFlags;
+import android.view.WindowManager.LayoutParams;
+
+import java.util.List;
+
+/**
+ * A helper to determine the {@link InputConfigFlags} that control the behavior of an input window
+ * from several WM attributes.
+ */
+class InputConfigAdapter {
+ private InputConfigAdapter() {}
+
+ /** Describes a mapping from a flag value to a {@link InputConfigFlags} value. */
+ private static class FlagMapping {
+ final int mFlag;
+ final int mInputConfig;
+ final boolean mInverted;
+
+ FlagMapping(int flag, int inputConfig, boolean inverted) {
+ mFlag = flag;
+ mInputConfig = inputConfig;
+ mInverted = inverted;
+ }
+ }
+
+ /**
+ * A mapping from {@link LayoutParams.InputFeatureFlags} to {@link InputConfigFlags} for
+ * input configurations that can be mapped directly from a corresponding LayoutParams input
+ * feature.
+ */
+ private static final List<FlagMapping> INPUT_FEATURE_TO_CONFIG_MAP = List.of(
+ new FlagMapping(
+ LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
+ InputConfig.NO_INPUT_CHANNEL, false /* inverted */),
+ new FlagMapping(
+ LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY,
+ InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */),
+ new FlagMapping(
+ LayoutParams.INPUT_FEATURE_SPY,
+ InputConfig.SPY, false /* inverted */));
+
+ @InputConfigFlags
+ private static final int INPUT_FEATURE_TO_CONFIG_MASK =
+ computeMask(INPUT_FEATURE_TO_CONFIG_MAP);
+
+ /**
+ * A mapping from {@link LayoutParams.Flags} to {@link InputConfigFlags} for input
+ * configurations that can be mapped directly from a corresponding LayoutParams flag.
+ *
+ * NOTE: The layout params flag {@link LayoutParams#FLAG_NOT_FOCUSABLE} is not handled by this
+ * adapter, and must be handled explicitly.
+ */
+ private static final List<FlagMapping> LAYOUT_PARAM_FLAG_TO_CONFIG_MAP = List.of(
+ new FlagMapping(
+ LayoutParams.FLAG_NOT_TOUCHABLE,
+ InputConfig.NOT_TOUCHABLE, false /* inverted */),
+ new FlagMapping(
+ LayoutParams.FLAG_SPLIT_TOUCH,
+ InputConfig.PREVENT_SPLITTING, true /* inverted */),
+ new FlagMapping(
+ LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ InputConfig.WATCH_OUTSIDE_TOUCH, false /* inverted */),
+ new FlagMapping(
+ LayoutParams.FLAG_SLIPPERY,
+ InputConfig.SLIPPERY, false /* inverted */));
+
+ @InputConfigFlags
+ private static final int LAYOUT_PARAM_FLAG_TO_CONFIG_MASK =
+ computeMask(LAYOUT_PARAM_FLAG_TO_CONFIG_MAP);
+
+ /**
+ * Returns a mask of all the input config flags configured by
+ * {@link #getInputConfigFromWindowParams(int, int, int)}.
+ */
+ @InputConfigFlags
+ static int getMask() {
+ return LAYOUT_PARAM_FLAG_TO_CONFIG_MASK | INPUT_FEATURE_TO_CONFIG_MASK
+ | InputConfig.IS_WALLPAPER;
+ }
+
+ /**
+ * Get the {@link InputConfigFlags} value that provides the input window behavior specified by
+ * the given WindowManager attributes.
+ *
+ * Use {@link #getMask()} to get the mask of all the input config flags set by this method.
+ *
+ * @param type the window type
+ * @param flags the window flags
+ * @param inputFeatures the input feature flags
+ */
+ @InputConfigFlags
+ static int getInputConfigFromWindowParams(@LayoutParams.WindowType int type,
+ @LayoutParams.Flags int flags, @LayoutParams.InputFeatureFlags int inputFeatures) {
+ return (type == LayoutParams.TYPE_WALLPAPER ? InputConfig.IS_WALLPAPER : 0)
+ | applyMapping(flags, LAYOUT_PARAM_FLAG_TO_CONFIG_MAP)
+ | applyMapping(inputFeatures, INPUT_FEATURE_TO_CONFIG_MAP);
+ }
+
+ @InputConfigFlags
+ private static int applyMapping(int flags, List<FlagMapping> flagToConfigMap) {
+ int inputConfig = 0;
+ for (final FlagMapping mapping : flagToConfigMap) {
+ final boolean flagSet = (flags & mapping.mFlag) != 0;
+ if (flagSet != mapping.mInverted) {
+ inputConfig |= mapping.mInputConfig;
+ }
+ }
+ return inputConfig;
+ }
+
+ @InputConfigFlags
+ private static int computeMask(List<FlagMapping> flagToConfigMap) {
+ int mask = 0;
+ for (final FlagMapping mapping : flagToConfigMap) {
+ mask |= mapping.mInputConfig;
+ }
+ return mask;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index cbd5646968d7..59be3e05f2c0 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -22,6 +22,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -70,19 +71,14 @@ class InputConsumerImpl implements IBinder.DeathRecipient {
mWindowHandle.name = name;
mWindowHandle.token = mClientChannel.getToken();
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
- mWindowHandle.layoutParamsFlags = 0;
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mWindowHandle.visible = true;
- mWindowHandle.focusable = false;
- mWindowHandle.hasWallpaper = false;
- mWindowHandle.paused = false;
mWindowHandle.ownerPid = Process.myPid();
mWindowHandle.ownerUid = Process.myUid();
- mWindowHandle.inputFeatures = 0;
mWindowHandle.scaleFactor = 1.0f;
- mWindowHandle.trustedOverlay = true;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
- mInputSurface = mService.makeSurfaceBuilder(mService.mRoot.getDisplayContent(displayId).getSession())
+ mInputSurface = mService.makeSurfaceBuilder(
+ mService.mRoot.getDisplayContent(displayId).getSession())
.setContainerLayer()
.setName("Input Consumer " + name)
.setCallsite("InputConsumerImpl")
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 31ae864fc090..8038f4404799 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -21,7 +21,6 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
@@ -53,6 +52,7 @@ import android.annotation.Nullable;
import android.graphics.Region;
import android.os.Handler;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
@@ -61,6 +61,7 @@ import android.util.Slog;
import android.view.InputChannel;
import android.view.InputWindowHandle;
import android.view.SurfaceControl;
+import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -221,15 +222,13 @@ final class InputMonitor {
inputChannel, clientPid, clientUser, mDisplayId);
switch (name) {
case INPUT_CONSUMER_WALLPAPER:
- consumer.mWindowHandle.hasWallpaper = true;
+ consumer.mWindowHandle.inputConfig |= InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER;
break;
case INPUT_CONSUMER_PIP:
- // The touchable region of the Pip input window is cropped to the bounds of the
- // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
- consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
+ // This is a valid consumer type, but we don't need any additional configurations.
break;
case INPUT_CONSUMER_RECENTS_ANIMATION:
- consumer.mWindowHandle.focusable = true;
+ consumer.mWindowHandle.inputConfig &= ~InputConfig.NOT_FOCUSABLE;
break;
default:
throw new IllegalArgumentException("Illegal input consumer : " + name
@@ -247,11 +246,24 @@ final class InputMonitor {
inputWindowHandle.setToken(w.mInputChannelToken);
inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
- inputWindowHandle.setInputFeatures(w.mAttrs.inputFeatures);
inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
- inputWindowHandle.setVisible(w.isVisible());
inputWindowHandle.setWindowToken(w.mClient);
+ // Update layout params flags to force the window to be not touch modal. We do this to
+ // restrict the window's touchable region to the task even if it requests touches outside
+ // its window bounds. An example is a dialog in primary split should get touches outside its
+ // window within the primary task but should not get any touches going to the secondary
+ // task.
+ int flags = w.mAttrs.flags;
+ if (w.mAttrs.isModal()) {
+ flags = flags | FLAG_NOT_TOUCH_MODAL;
+ }
+ inputWindowHandle.setLayoutParamsFlags(flags);
+ inputWindowHandle.setInputConfigMasked(
+ InputConfigAdapter.getInputConfigFromWindowParams(
+ w.mAttrs.type, flags, w.mAttrs.inputFeatures),
+ InputConfigAdapter.getMask());
+
final boolean focusable = w.canReceiveKeys()
&& (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
inputWindowHandle.setFocusable(focusable);
@@ -270,17 +282,6 @@ final class InputMonitor {
// what is on screen to what is actually being touched in the UI.
inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
- // Update layout params flags to force the window to be not touch modal. We do this to
- // restrict the window's touchable region to the task even if it request touches outside its
- // window bounds. An example is a dialog in primary split should get touches outside its
- // window within the primary task but should not get any touches going to the secondary
- // task.
- int flags = w.mAttrs.flags;
- if (w.mAttrs.isModal()) {
- flags = flags | FLAG_NOT_TOUCH_MODAL;
- }
- inputWindowHandle.setLayoutParamsFlags(flags);
-
boolean useSurfaceBoundsAsTouchRegion = false;
SurfaceControl touchableRegionCrop = null;
final Task task = w.getTask();
@@ -522,6 +523,8 @@ final class InputMonitor {
layer = layer != null ? layer : activeRecents;
// Handle edge-case for SUW where windows don't exist yet
if (layer.getSurfaceControl() != null) {
+ mRecentsAnimationInputConsumer.mWindowHandle
+ .replaceTouchableRegionWithCrop(layer.getSurfaceControl());
mRecentsAnimationInputConsumer.show(mInputTransaction, layer);
mAddRecentsAnimationInputConsumerHandle = false;
}
@@ -588,6 +591,8 @@ final class InputMonitor {
if (mAddWallpaperInputConsumerHandle) {
if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisible()) {
+ mWallpaperInputConsumer.mWindowHandle
+ .replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
// Add the wallpaper input consumer above the first visible wallpaper.
mWallpaperInputConsumer.show(mInputTransaction, w);
mAddWallpaperInputConsumerHandle = false;
@@ -629,24 +634,27 @@ final class InputMonitor {
static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
WindowState w) {
- populateOverlayInputInfo(inputWindowHandle, w.isVisible());
+ populateOverlayInputInfo(inputWindowHandle);
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
}
// This would reset InputWindowHandle fields to prevent it could be found by input event.
// We need to check if any new field of InputWindowHandle could impact the result.
@VisibleForTesting
- static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
- boolean isVisible) {
+ static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle) {
inputWindowHandle.setDispatchingTimeoutMillis(0); // It should never receive input.
- inputWindowHandle.setVisible(isVisible);
inputWindowHandle.setFocusable(false);
- inputWindowHandle.setInputFeatures(INPUT_FEATURE_NO_INPUT_CHANNEL);
// The input window handle without input channel must not have a token.
inputWindowHandle.setToken(null);
inputWindowHandle.setScaleFactor(1f);
- inputWindowHandle.setLayoutParamsFlags(
- FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE);
+ final int defaultType = WindowManager.LayoutParams.TYPE_APPLICATION;
+ inputWindowHandle.setLayoutParamsType(defaultType);
+ inputWindowHandle.setInputConfigMasked(
+ InputConfigAdapter.getInputConfigFromWindowParams(
+ defaultType,
+ FLAG_NOT_TOUCHABLE,
+ INPUT_FEATURE_NO_INPUT_CHANNEL),
+ InputConfigAdapter.getMask());
inputWindowHandle.clearTouchableRegion();
inputWindowHandle.setTouchableRegionCrop(null);
}
@@ -664,7 +672,7 @@ final class InputMonitor {
inputWindowHandle.setName(name);
inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
inputWindowHandle.setTrustedOverlay(true);
- populateOverlayInputInfo(inputWindowHandle, true /* isVisible */);
+ populateOverlayInputInfo(inputWindowHandle);
setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
}
diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
index 142d2933f046..301c1846249f 100644
--- a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
+++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
@@ -20,10 +20,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Region;
import android.os.IBinder;
+import android.os.InputConfig;
import android.view.IWindow;
import android.view.InputApplicationHandle;
import android.view.InputWindowHandle;
+import android.view.InputWindowHandle.InputConfigFlags;
import android.view.SurfaceControl;
+import android.view.WindowManager;
import java.util.Objects;
@@ -31,8 +34,10 @@ import java.util.Objects;
* The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary
* updates to surface, e.g. if there are no changes, then skip invocation of
* {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}.
+ * It also sets the {@link InputConfigFlags} values for the input window.
*/
class InputWindowHandleWrapper {
+
/** The wrapped handle should not be directly exposed to avoid untracked changes. */
private final @NonNull InputWindowHandle mHandle;
@@ -65,7 +70,20 @@ class InputWindowHandleWrapper {
}
boolean isFocusable() {
- return mHandle.focusable;
+ return (mHandle.inputConfig & InputConfig.NOT_FOCUSABLE) == 0;
+ }
+
+ boolean isPaused() {
+ return (mHandle.inputConfig & InputConfig.PAUSE_DISPATCHING) != 0;
+ }
+
+ boolean isTrustedOverlay() {
+ return (mHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
+ }
+
+ boolean hasWallpaper() {
+ return (mHandle.inputConfig & InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER)
+ != 0;
}
InputApplicationHandle getInputApplicationHandle() {
@@ -96,7 +114,7 @@ class InputWindowHandleWrapper {
mChanged = true;
}
- void setLayoutParamsFlags(int flags) {
+ void setLayoutParamsFlags(@WindowManager.LayoutParams.Flags int flags) {
if (mHandle.layoutParamsFlags == flags) {
return;
}
@@ -136,19 +154,11 @@ class InputWindowHandleWrapper {
mChanged = true;
}
- void setVisible(boolean visible) {
- if (mHandle.visible == visible) {
- return;
- }
- mHandle.visible = visible;
- mChanged = true;
- }
-
void setFocusable(boolean focusable) {
- if (mHandle.focusable == focusable) {
+ if (isFocusable() == focusable) {
return;
}
- mHandle.focusable = focusable;
+ mHandle.setInputConfig(InputConfig.NOT_FOCUSABLE, !focusable);
mChanged = true;
}
@@ -161,26 +171,27 @@ class InputWindowHandleWrapper {
}
void setHasWallpaper(boolean hasWallpaper) {
- if (mHandle.hasWallpaper == hasWallpaper) {
+ if (this.hasWallpaper() == hasWallpaper) {
return;
}
- mHandle.hasWallpaper = hasWallpaper;
+ mHandle.setInputConfig(InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
+ hasWallpaper);
mChanged = true;
}
void setPaused(boolean paused) {
- if (mHandle.paused == paused) {
+ if (isPaused() == paused) {
return;
}
- mHandle.paused = paused;
+ mHandle.setInputConfig(InputConfig.PAUSE_DISPATCHING, paused);
mChanged = true;
}
void setTrustedOverlay(boolean trustedOverlay) {
- if (mHandle.trustedOverlay == trustedOverlay) {
+ if (isTrustedOverlay() == trustedOverlay) {
return;
}
- mHandle.trustedOverlay = trustedOverlay;
+ mHandle.setInputConfig(InputConfig.TRUSTED_OVERLAY, trustedOverlay);
mChanged = true;
}
@@ -208,14 +219,6 @@ class InputWindowHandleWrapper {
mChanged = true;
}
- void setInputFeatures(int features) {
- if (mHandle.inputFeatures == features) {
- return;
- }
- mHandle.inputFeatures = features;
- mChanged = true;
- }
-
void setDisplayId(int displayId) {
if (mHandle.displayId == displayId) {
return;
@@ -276,8 +279,14 @@ class InputWindowHandleWrapper {
mChanged = true;
}
- boolean isTrustedOverlay() {
- return mHandle.trustedOverlay;
+ void setInputConfigMasked(@InputConfigFlags int inputConfig, @InputConfigFlags int mask) {
+ final int inputConfigMasked = inputConfig & mask;
+ if (inputConfigMasked == (mHandle.inputConfig & mask)) {
+ return;
+ }
+ mHandle.inputConfig &= ~mask;
+ mHandle.inputConfig |= inputConfigMasked;
+ mChanged = true;
}
@Override
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 4fdb1f7930f5..398816b331cb 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -583,10 +583,10 @@ class InsetsPolicy {
// Notification shade has control anyways, no reason to force anything.
return focusedWin;
}
- if (mPolicy.isForceShowNavigationBarEnabled()
+ if (mPolicy.isForceShowNavigationBarEnabled() && focusedWin != null
&& focusedWin.getActivityType() == ACTIVITY_TYPE_STANDARD) {
- // When "force show navigation bar" is enabled, it means we are in kid navigation bar
- // and 3-button navigation bar mode. In this mode, the navigation bar is forcibly shown
+ // When "force show navigation bar" is enabled, it means both force visible is true, and
+ // we are in 3-button navigation. In this mode, the navigation bar is forcibly shown
// when activity type is ACTIVITY_TYPE_STANDARD which means Launcher or Recent could
// still control the navigation bar in this mode.
return null;
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 4b98013a99cc..40df02c176e5 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -24,6 +24,7 @@ import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Process;
import android.view.GestureDetector;
import android.view.InputChannel;
@@ -290,16 +291,12 @@ public class Letterbox {
win.getDisplayId());
mWindowHandle.name = name;
mWindowHandle.token = mToken;
- mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_SLIPPERY;
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mWindowHandle.visible = true;
mWindowHandle.ownerPid = Process.myPid();
mWindowHandle.ownerUid = Process.myUid();
mWindowHandle.scaleFactor = 1.0f;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SLIPPERY;
}
void updateTouchableRegion(Rect frame) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b9cd657da0e2..235533341433 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -149,6 +149,7 @@ import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.UserState;
+import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.policy.WindowManagerPolicy;
import java.io.FileDescriptor;
@@ -2727,9 +2728,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return false;
}
- Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
+ Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@Nullable Task candidateTask, boolean onTop) {
- return getLaunchRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
+ return getOrCreateRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
null /* launchParams */, 0 /* launchFlags */);
}
@@ -2744,63 +2745,68 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @param launchFlags The launch flags for this launch.
* @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
* @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
- * @return The root task to use for the launch or INVALID_TASK_ID.
+ * @return The root task to use for the launch.
*/
- Task getLaunchRootTask(@Nullable ActivityRecord r,
+ Task getOrCreateRootTask(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask,
@Nullable Task sourceTask, boolean onTop,
@Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags) {
- int taskId = INVALID_TASK_ID;
- int displayId = INVALID_DISPLAY;
- TaskDisplayArea taskDisplayArea = null;
-
- // We give preference to the launch preference in activity options.
+ // First preference goes to the launch root task set in the activity options.
if (options != null) {
- taskId = options.getLaunchTaskId();
- displayId = options.getLaunchDisplayId();
- final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
- taskDisplayArea = daToken != null
- ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
-
- final Task rootTask = Task.fromWindowContainerToken(options.getLaunchRootTask());
- if (rootTask != null) {
- return rootTask;
+ final Task candidateRoot = Task.fromWindowContainerToken(options.getLaunchRootTask());
+ if (canLaunchOnDisplay(r, candidateRoot)) {
+ return candidateRoot;
}
}
- // First preference for root task goes to the task Id set in the activity options. Use
- // the root task associated with that if possible.
- if (taskId != INVALID_TASK_ID) {
- // Temporarily set the task id to invalid in case in re-entry.
- options.setLaunchTaskId(INVALID_TASK_ID);
- final Task task = anyTaskForId(taskId,
- MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
- options.setLaunchTaskId(taskId);
- if (task != null) {
- return task.getRootTask();
+ // Next preference goes to the task id set in the activity options.
+ if (options != null) {
+ final int candidateTaskId = options.getLaunchTaskId();
+ if (candidateTaskId != INVALID_TASK_ID) {
+ // Temporarily set the task id to invalid in case in re-entry.
+ options.setLaunchTaskId(INVALID_TASK_ID);
+ final Task task = anyTaskForId(candidateTaskId,
+ MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
+ options.setLaunchTaskId(candidateTaskId);
+ if (canLaunchOnDisplay(r, task)) {
+ return task.getRootTask();
+ }
}
}
- final int activityType = resolveActivityType(r, options, candidateTask);
- Task rootTask = null;
-
- // Next preference for root task goes to the taskDisplayArea candidate.
- if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null
- && canLaunchOnDisplay(r, launchParams.mPreferredTaskDisplayArea.getDisplayId())) {
+ // Next preference goes to the TaskDisplayArea candidate from launchParams
+ // or activity options.
+ TaskDisplayArea taskDisplayArea = null;
+ if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
+ } else if (options != null) {
+ final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
+ taskDisplayArea = daToken != null
+ ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
+ if (taskDisplayArea == null) {
+ final int launchDisplayId = options.getLaunchDisplayId();
+ if (launchDisplayId != INVALID_DISPLAY) {
+ final DisplayContent displayContent = getDisplayContent(launchDisplayId);
+ if (displayContent != null) {
+ taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
+ }
+ }
+ }
}
- if (taskDisplayArea == null && displayId != INVALID_DISPLAY
- && canLaunchOnDisplay(r, displayId)) {
- taskDisplayArea = getDisplayContent(displayId).getDefaultTaskDisplayArea();
- }
+
+ final int activityType = resolveActivityType(r, options, candidateTask);
if (taskDisplayArea != null) {
- return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
- sourceTask, launchParams, launchFlags, activityType, onTop);
+ if (canLaunchOnDisplay(r, taskDisplayArea.getDisplayId())) {
+ return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
+ sourceTask, launchParams, launchFlags, activityType, onTop);
+ } else {
+ taskDisplayArea = null;
+ }
}
// Give preference to the root task and display of the input task and activity if they
// match the mode we want to launch into.
- TaskDisplayArea container = null;
+ Task rootTask = null;
if (candidateTask != null) {
rootTask = candidateTask.getRootTask();
}
@@ -2810,10 +2816,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
int windowingMode = launchParams != null ? launchParams.mWindowingMode
: WindowConfiguration.WINDOWING_MODE_UNDEFINED;
if (rootTask != null) {
- container = rootTask.getDisplayArea();
- if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
+ taskDisplayArea = rootTask.getDisplayArea();
+ if (taskDisplayArea != null
+ && canLaunchOnDisplay(r, taskDisplayArea.mDisplayContent.mDisplayId)) {
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- windowingMode = container.resolveWindowingMode(r, options, candidateTask);
+ windowingMode = taskDisplayArea.resolveWindowingMode(r, options, candidateTask);
}
// Always allow organized tasks that created by organizer since the activity type
// of an organized task is decided by the activity type of its top child, which
@@ -2822,19 +2829,32 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|| rootTask.mCreatedByOrganizer) {
return rootTask;
}
+ } else {
+ taskDisplayArea = null;
}
+
}
- if (container == null
- || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
- container = getDefaultTaskDisplayArea();
- if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- windowingMode = container.resolveWindowingMode(r, options, candidateTask);
- }
+ // Falling back to default task container
+ if (taskDisplayArea == null) {
+ taskDisplayArea = getDefaultTaskDisplayArea();
+ }
+ return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, sourceTask,
+ launchParams, launchFlags, activityType, onTop);
+ }
+
+ private boolean canLaunchOnDisplay(ActivityRecord r, Task task) {
+ if (task == null) {
+ Slog.w(TAG, "canLaunchOnDisplay(), invalid task: " + task);
+ return false;
+ }
+
+ if (!task.isAttached()) {
+ Slog.w(TAG, "canLaunchOnDisplay(), Task is not attached: " + task);
+ return false;
}
- return container.getOrCreateRootTask(r, options, candidateTask, sourceTask, launchParams,
- launchFlags, activityType, onTop);
+ return canLaunchOnDisplay(r, task.getTaskDisplayArea().getDisplayId());
}
/** @return true if activity record is null or can be launched on provided display. */
@@ -2842,7 +2862,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (r == null) {
return true;
}
- return r.canBeLaunchedOnDisplay(displayId);
+ if (!r.canBeLaunchedOnDisplay(displayId)) {
+ Slog.w(TAG, "Not allow to launch " + r + " on display " + displayId);
+ return false;
+ }
+ return true;
}
int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@@ -3212,12 +3236,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (aOptions != null) {
// Resolve the root task the task should be placed in now based on options
// and reparent if needed.
- final Task launchRootTask =
- getLaunchRootTask(null, aOptions, task, onTop);
- if (launchRootTask != null && task.getRootTask() != launchRootTask) {
+ final Task targetRootTask =
+ getOrCreateRootTask(null, aOptions, task, onTop);
+ if (targetRootTask != null && task.getRootTask() != targetRootTask) {
final int reparentMode = onTop
? REPARENT_MOVE_ROOT_TASK_TO_FRONT : REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
- task.reparent(launchRootTask, onTop, reparentMode, ANIMATE, DEFER_RESUME,
+ task.reparent(targetRootTask, onTop, reparentMode, ANIMATE, DEFER_RESUME,
"anyTaskForId");
}
}
@@ -3309,6 +3333,36 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
/**
+ * Iterate over all task fragments, to see if there exists one that meets the
+ * PermissionPolicyService's criteria to show a permission dialog.
+ */
+ public int getTaskToShowPermissionDialogOn(String pkgName, int uid) {
+ PermissionPolicyInternal pPi = mService.getPermissionPolicyInternal();
+ if (pPi == null) {
+ return INVALID_TASK_ID;
+ }
+
+ final int[] validTaskId = {INVALID_TASK_ID};
+ forAllLeafTaskFragments(fragment -> {
+ ActivityRecord record = fragment.getActivity((r) -> {
+ // skip hidden (or about to hide) apps, or the permission dialog
+ return r.canBeTopRunning() && r.isVisibleRequested()
+ && !pPi.isIntentToPermissionDialog(r.intent);
+ });
+ if (record != null && record.isUid(uid)
+ && Objects.equals(pkgName, record.packageName)
+ && pPi.shouldShowNotificationDialogForTask(record.getTask().getTaskInfo(),
+ pkgName, record.intent)) {
+ validTaskId[0] = record.getTask().mTaskId;
+ return true;
+ }
+ return false;
+ });
+
+ return validTaskId[0];
+ }
+
+ /**
* Dumps the activities matching the given {@param name} in the either the focused root task
* or all visible root tasks if {@param dumpVisibleRootTasksOnly} is true.
*/
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 3d6d1825adc7..1ec191ed7c05 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -57,8 +57,6 @@ class RunningTasks {
private ArraySet<Integer> mProfileIds;
private boolean mAllowed;
private boolean mFilterOnlyVisibleRecents;
- private Task mTopDisplayFocusRootTask;
- private Task mTopDisplayAdjacentTask;
private RecentTasks mRecentTasks;
private boolean mKeepIntentExtra;
@@ -78,17 +76,9 @@ class RunningTasks {
mAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED;
mFilterOnlyVisibleRecents =
(flags & FLAG_FILTER_ONLY_VISIBLE_RECENTS) == FLAG_FILTER_ONLY_VISIBLE_RECENTS;
- mTopDisplayFocusRootTask = root.getTopDisplayFocusedRootTask();
mRecentTasks = root.mService.getRecentTasks();
mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA;
- if (mTopDisplayFocusRootTask != null
- && mTopDisplayFocusRootTask.getAdjacentTaskFragment() != null) {
- mTopDisplayAdjacentTask = mTopDisplayFocusRootTask.getAdjacentTaskFragment().asTask();
- } else {
- mTopDisplayAdjacentTask = null;
- }
-
final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
PooledLambda.__(Task.class));
root.forAllLeafTasks(c, false);
@@ -132,18 +122,15 @@ class RunningTasks {
return;
}
- final Task rootTask = task.getRootTask();
- if (rootTask == mTopDisplayFocusRootTask && rootTask.getTopMostTask() == task) {
- // For the focused top root task, update the last root task active time so that it
- // can be used to determine the order of the tasks (it may not be set for newly
- // created tasks)
+ if (task.isVisible()) {
+ // For the visible task, update the last active time so that it can be used to determine
+ // the order of the tasks (it may not be set for newly created tasks)
task.touchActiveTime();
- } else if (rootTask == mTopDisplayAdjacentTask && rootTask.getTopMostTask() == task) {
- // The short-term workaround for launcher could get suitable running task info in
- // split screen.
- task.touchActiveTime();
- // TreeSet doesn't allow same value and make sure this task is lower than focus one.
- task.lastActiveTime--;
+ if (!task.isFocused()) {
+ // TreeSet doesn't allow the same value and make sure this task is lower than the
+ // focused one.
+ task.lastActiveTime -= mTmpSortedSet.size();
+ }
}
mTmpSortedSet.add(task);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7fe34f47c53c..b3ae60287534 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -504,13 +504,6 @@ class Task extends TaskFragment {
*/
boolean mInRemoveTask;
- // When non-null, this is a transaction that will get applied on the next frame returned after
- // a relayout is requested from the client. While this is only valid on a leaf task; since the
- // transaction can effect an ancestor task, this also needs to keep track of the ancestor task
- // that this transaction manipulates because deferUntilFrame acts on individual surfaces.
- SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
- Task mMainWindowSizeChangeTask;
-
private final AnimatingActivityRegistry mAnimatingActivityRegistry =
new AnimatingActivityRegistry();
@@ -4287,7 +4280,7 @@ class Task extends TaskFragment {
/**
* @return true if the task is currently focused.
*/
- private boolean isFocused() {
+ boolean isFocused() {
if (mDisplayContent == null || mDisplayContent.mFocusedApp == null) {
return false;
}
@@ -4390,17 +4383,16 @@ class Task extends TaskFragment {
leaf.setMainWindowSizeChangeTransaction(t, origin);
return;
}
- mMainWindowSizeChangeTransaction = t;
- mMainWindowSizeChangeTask = t == null ? null : origin;
- }
-
- SurfaceControl.Transaction getMainWindowSizeChangeTransaction() {
- return mMainWindowSizeChangeTransaction;
+ final WindowState w = getTopVisibleAppMainWindow();
+ if (w != null) {
+ w.applyWithNextDraw((d) -> {
+ d.merge(t);
+ });
+ } else {
+ t.apply();
+ }
}
- Task getMainWindowSizeChangeTask() {
- return mMainWindowSizeChangeTask;
- }
void setActivityWindowingMode(int windowingMode) {
PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setWindowingMode,
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index afc3087f4ee9..3411104dbff0 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -516,12 +516,13 @@ class TaskFragment extends WindowContainer<WindowContainer> {
* @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
*/
boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) {
- if ((a.info.flags & FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING)
- == FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING) {
- return true;
- }
+ return isAllowedToEmbedActivityInUntrustedMode(a)
+ || isAllowedToEmbedActivityInTrustedMode(a);
+ }
- return isAllowedToEmbedActivityInTrustedMode(a);
+ boolean isAllowedToEmbedActivityInUntrustedMode(@NonNull ActivityRecord a) {
+ return (a.info.flags & FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING)
+ == FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
}
/**
@@ -531,7 +532,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
* <li>the activity has declared the organizer host as trusted explicitly via known
* certificate.</li>
*/
- private boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
+ boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
if (UserHandle.getAppId(mTaskFragmentOrganizerUid) == SYSTEM_UID) {
// The system is trusted to embed other apps securely and for all users.
return true;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 348cfb62582e..47c397d12720 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -40,6 +40,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.Process;
import android.os.RemoteException;
import android.os.Trace;
@@ -219,30 +220,17 @@ class TaskPositioner implements IBinder.DeathRecipient {
displayContent.getDisplayId());
mDragWindowHandle.name = TAG;
mDragWindowHandle.token = mClientChannel.getToken();
- mDragWindowHandle.layoutParamsFlags = 0;
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- mDragWindowHandle.visible = true;
- // When dragging the window around, we do not want to steal focus for the window.
- mDragWindowHandle.focusable = false;
- mDragWindowHandle.hasWallpaper = false;
- mDragWindowHandle.paused = false;
mDragWindowHandle.ownerPid = Process.myPid();
mDragWindowHandle.ownerUid = Process.myUid();
- mDragWindowHandle.inputFeatures = 0;
mDragWindowHandle.scaleFactor = 1.0f;
+ // When dragging the window around, we do not want to steal focus for the window.
+ mDragWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
// The drag window cannot receive new touches.
mDragWindowHandle.touchableRegion.setEmpty();
- // The drag window covers the entire display.
- final Rect displayBounds = mTmpRect;
- displayContent.getBounds(mTmpRect);
- mDragWindowHandle.frameLeft = displayBounds.left;
- mDragWindowHandle.frameTop = displayBounds.top;
- mDragWindowHandle.frameRight = displayBounds.right;
- mDragWindowHandle.frameBottom = displayBounds.bottom;
-
// Pause rotations before a drag.
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position");
mDisplayContent.getDisplayRotation().pause();
@@ -250,6 +238,8 @@ class TaskPositioner implements IBinder.DeathRecipient {
// Notify InputMonitor to take mDragWindowHandle.
mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
+ final Rect displayBounds = mTmpRect;
+ displayContent.getBounds(displayBounds);
final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 8f24f2615fac..68bf2b2424e7 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -83,17 +83,18 @@ class TaskPositioningController {
return;
}
- mTransaction.show(mInputSurface);
- mTransaction.setInputWindowInfo(mInputSurface, h);
- mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
-
final Display display = dc.getDisplay();
final Point p = new Point();
display.getRealSize(p);
-
mTmpClipRect.set(0, 0, p.x, p.y);
- mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
- mTransaction.syncInputWindows().apply();
+
+ mTransaction.show(mInputSurface)
+ .setInputWindowInfo(mInputSurface, h)
+ .setLayer(mInputSurface, Integer.MAX_VALUE)
+ .setPosition(mInputSurface, 0, 0)
+ .setCrop(mInputSurface, mTmpClipRect)
+ .syncInputWindows()
+ .apply();
}
boolean startMovingTask(IWindow window, float startX, float startY) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 29d17429fa6a..4c23f3991c58 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -574,6 +574,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
false /* disableImeIcon */);
}
}
+ dc.removeImeSurfaceImmediately();
dc.handleCompleteDeferredRemoval();
}
}
@@ -1526,6 +1527,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
if (task != null && task.voiceSession != null) {
flags |= FLAG_IS_VOICE_INTERACTION;
}
+ if (task != null && task.isTranslucent(null)) {
+ flags |= FLAG_TRANSLUCENT;
+ }
final ActivityRecord record = wc.asActivityRecord();
if (record != null) {
if (record.mUseTransferredAnimation) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 56014adb705d..dab02dec5f7d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -73,6 +73,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Debug;
@@ -3807,7 +3808,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
private void setTaskBackgroundColor(@ColorInt int backgroundColor) {
TaskDisplayArea taskDisplayArea = getTaskDisplayArea();
- if (taskDisplayArea != null) {
+ if (taskDisplayArea != null && backgroundColor != Color.TRANSPARENT) {
taskDisplayArea.setBackgroundColor(backgroundColor);
// Atomic counter to make sure the clearColor callback is only called one.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fd69f54a7a10..49d9b65dde68 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -141,6 +141,7 @@ import static com.android.server.wm.WindowManagerServiceDumpProto.HARD_KEYBOARD_
import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
+import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID;
import android.Manifest;
import android.Manifest.permission;
@@ -191,6 +192,7 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.IRemoteCallback;
+import android.os.InputConfig;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
@@ -3934,7 +3936,13 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
+ // The bounds returned by the task represent the task's position on the screen. However,
+ // we need to specify a crop relative to the task's surface control. Therefore, shift
+ // the task's bounds to 0,0 so that we have the correct size and position within the
+ // task's surface control.
task.getBounds(mTmpRect);
+ mTmpRect.offsetTo(0, 0);
+
final SurfaceControl sc = task.getSurfaceControl();
final SurfaceControl.ScreenshotHardwareBuffer buffer = SurfaceControl.captureLayers(
layerCaptureArgsBuilder.setLayer(sc).setSourceCrop(mTmpRect).build());
@@ -6431,9 +6439,13 @@ public class WindowManagerService extends IWindowManager.Stub
imeWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW);
}
proto.write(DISPLAY_FROZEN, mDisplayFrozen);
- final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
proto.write(HARD_KEYBOARD_AVAILABLE, mHardKeyboardAvailable);
+
+ // This is always true for now since we still update the window frames at the server side.
+ // 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);
}
private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
@@ -8441,43 +8453,48 @@ public class WindowManagerService extends IWindowManager.Stub
}
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
- int displayId, SurfaceControl surface, String name,
- InputApplicationHandle applicationHandle, int flags,
- int privateFlags, int type, Region region, IWindow window) {
- InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
+ int displayId, SurfaceControl surface, String name,
+ InputApplicationHandle applicationHandle, int flags,
+ int privateFlags, int type, Region region, IWindow window) {
+ final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
h.token = channelToken;
h.setWindowToken(window);
h.name = name;
flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
- final int sanitizedFlags = flags & (FLAG_NOT_TOUCHABLE
- | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);
- h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
+ final int sanitizedLpFlags =
+ (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
+ | LayoutParams.FLAG_NOT_TOUCH_MODAL;
h.layoutParamsType = type;
- h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
- h.focusable = (flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0;
- h.hasWallpaper = false;
- h.paused = false;
+ h.layoutParamsFlags = sanitizedLpFlags;
+
+ // Do not allow any input features to be set without sanitizing them first.
+ h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
+ type, sanitizedLpFlags, 0 /*inputFeatures*/);
+
+
+ if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ h.inputConfig |= InputConfig.NOT_FOCUSABLE;
+ }
+ // Check private trusted overlay flag to set trustedOverlay field of input window handle.
+ if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
+ h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
+ }
+
+ h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
h.ownerUid = callingUid;
h.ownerPid = callingPid;
- // Do not allow any input features to be set without sanitizing them first.
- h.inputFeatures = 0;
-
if (region == null) {
- h.replaceTouchableRegionWithCrop(null);
+ h.replaceTouchableRegionWithCrop = true;
} else {
h.touchableRegion.set(region);
- h.replaceTouchableRegionWithCrop = false;
- h.setTouchableRegionCrop(surface);
}
+ h.setTouchableRegionCrop(null /* use the input surface's bounds */);
- // Check private trusted overlay flag to set trustedOverlay field of input window handle.
- h.trustedOverlay = (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0;
-
- SurfaceControl.Transaction t = mTransactionFactory.get();
+ final SurfaceControl.Transaction t = mTransactionFactory.get();
t.setInputWindowInfo(surface, h);
t.apply();
t.close();
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index ce27d739e1b1..81344ac31108 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -701,6 +701,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
sendTaskFragmentOperationFailure(tf.getTaskFragmentOrganizer(),
errorCallbackToken,
convertStartFailureToThrowable(result, activityIntent));
+ } else {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
}
break;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d547275dcf0c..db687f627bfa 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -263,6 +263,7 @@ import dalvik.annotation.optimization.NeverCompile;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
@@ -1034,10 +1035,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* The system is more careful about restricted ones and may apply restrictions to them, while
* the unrestricted ones are considered safe.
*
- * @param outRestricted list to add restricted keep-clear areas to
- * @param outUnrestricted list to add unrestricted keep-clear areas to
+ * @param outRestricted collection to add restricted keep-clear areas to
+ * @param outUnrestricted collection to add unrestricted keep-clear areas to
*/
- void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) {
+ void getKeepClearAreas(Collection<Rect> outRestricted, Collection<Rect> outUnrestricted) {
final Matrix tmpMatrix = new Matrix();
final float[] tmpFloat9 = new float[9];
getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9);
@@ -1049,13 +1050,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* The system is more careful about restricted ones and may apply restrictions to them, while
* the unrestricted ones are considered safe.
*
- * @param outRestricted list to add restricted keep-clear areas to
- * @param outUnrestricted list to add unrestricted keep-clear areas to
+ * @param outRestricted collection to add restricted keep-clear areas to
+ * @param outUnrestricted collection to add unrestricted keep-clear areas to
* @param tmpMatrix a temporary matrix to be used for transformations
* @param float9 a temporary array of 9 floats
*/
- void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted, Matrix tmpMatrix,
- float[] float9) {
+ void getKeepClearAreas(Collection<Rect> outRestricted, Collection<Rect> outUnrestricted,
+ Matrix tmpMatrix, float[] float9) {
outRestricted.addAll(getRectsInScreenSpace(mKeepClearAreas, tmpMatrix, float9));
outUnrestricted.addAll(
getRectsInScreenSpace(mUnrestrictedKeepClearAreas, tmpMatrix, float9));
@@ -1189,6 +1190,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mActivityRecord != null
? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
getDisplayId()));
+ mInputWindowHandle.setFocusable(false);
mInputWindowHandle.setOwnerPid(s.mPid);
mInputWindowHandle.setOwnerUid(s.mUid);
mInputWindowHandle.setName(getName());
@@ -3583,6 +3585,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Clear animating flags now, since the surface is now gone. (Note this is true even
// if the surface is saved, to outside world the surface is still NO_SURFACE.)
mAnimatingExit = false;
+
+ if (useBLASTSync()) {
+ immediatelyNotifyBlastSync();
+ }
}
void onSurfaceShownChanged(boolean shown) {
@@ -5982,15 +5988,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
finishDrawing(null);
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
if (!useBLASTSync()) return;
-
- final Task task = getTask();
- if (task != null) {
- final SurfaceControl.Transaction t = task.getMainWindowSizeChangeTransaction();
- if (t != null) {
- mSyncTransaction.merge(t);
- }
- task.setMainWindowSizeChangeTransaction(null);
- }
}
@Override
@@ -6027,10 +6024,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mRedrawForSyncReported) {
return false;
}
- final Task task = getTask();
- if (task != null && task.getMainWindowSizeChangeTransaction() != null) {
- return true;
- }
return useBLASTSync();
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c17961e8a564..285a6d5bdf5f 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -442,50 +442,6 @@ class WindowStateAnimator {
return mService.useBLASTSync() && mWin.useBLASTSync();
}
- private boolean shouldConsumeMainWindowSizeTransaction() {
- // We only consume the transaction when the client is calling relayout
- // because this is the only time we know the frameNumber will be valid
- // due to the client renderer being paused. Put otherwise, only when
- // mInRelayout is true can we guarantee the next frame will contain
- // the most recent configuration.
- if (!mWin.mInRelayout) return false;
- // Since we can only do this for one window, we focus on the main application window
- if (mAttrType != TYPE_BASE_APPLICATION) return false;
- final Task task = mWin.getTask();
- if (task == null) return false;
- if (task.getMainWindowSizeChangeTransaction() == null) return false;
- // Likewise we only focus on the task root, since we can only use one window
- if (!mWin.mActivityRecord.isRootOfTask()) return false;
- return true;
- }
-
- void setSurfaceBoundariesLocked(SurfaceControl.Transaction t) {
- if (mSurfaceController == null) {
- return;
- }
-
- final WindowState w = mWin;
- final Task task = w.getTask();
- if (shouldConsumeMainWindowSizeTransaction()) {
- if (isInBlastSync()) {
- // If we're in a sync transaction, there's no need to call defer transaction.
- // The sync transaction will contain the buffer so the bounds change transaction
- // will only be applied with the buffer.
- t.merge(task.getMainWindowSizeChangeTransaction());
- task.setMainWindowSizeChangeTransaction(null);
- } else {
- mWin.applyWithNextDraw(finishedFrame -> {
- final SurfaceControl.Transaction sizeChangedTransaction =
- task.getMainWindowSizeChangeTransaction();
- if (sizeChangedTransaction != null) {
- finishedFrame.merge(sizeChangedTransaction);
- task.setMainWindowSizeChangeTransaction(null);
- }
- });
- }
- }
- }
-
void prepareSurfaceLocked(SurfaceControl.Transaction t) {
final WindowState w = mWin;
if (!hasSurface()) {
@@ -501,8 +457,6 @@ class WindowStateAnimator {
computeShownFrameLocked();
- setSurfaceBoundariesLocked(t);
-
if (w.isParentWindowHidden() || !w.isOnScreen()) {
hide(t, "prepareSurfaceLocked");
mWallpaperControllerLocked.hideWallpapers(w);
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 11714dc821af..9fa23c277d46 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -730,8 +730,7 @@ static jboolean android_location_gnss_hal_GnssNative_start_measurement_collectio
options.enableCorrVecOutputs = enableCorrVecOutputs;
options.intervalMs = intervalMs;
- return gnssMeasurementIface->setCallback(std::make_unique<gnss::GnssMeasurementCallback>(
- mCallbacksObj),
+ return gnssMeasurementIface->setCallback(std::make_unique<gnss::GnssMeasurementCallback>(),
options);
}
diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp
index 34ca559806c6..d37f3bd16ee8 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.cpp
+++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp
@@ -73,6 +73,11 @@ jmethodID method_satellitePvtBuilderSetVelocityEcef;
jmethodID method_satellitePvtBuilderSetClockInfo;
jmethodID method_satellitePvtBuilderSetIonoDelayMeters;
jmethodID method_satellitePvtBuilderSetTropoDelayMeters;
+jmethodID method_satellitePvtBuilderSetTimeOfClock;
+jmethodID method_satellitePvtBuilderSetTimeOfEphemeris;
+jmethodID method_satellitePvtBuilderSetIssueOfDataClock;
+jmethodID method_satellitePvtBuilderSetIssueOfDataEphemeris;
+jmethodID method_satellitePvtBuilderSetEphemerisSource;
jmethodID method_positionEcef;
jmethodID method_velocityEcef;
jmethodID method_clockInfo;
@@ -166,6 +171,21 @@ void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) {
method_satellitePvtBuilderSetTropoDelayMeters =
env->GetMethodID(class_satellitePvtBuilder, "setTropoDelayMeters",
"(D)Landroid/location/SatellitePvt$Builder;");
+ method_satellitePvtBuilderSetTimeOfClock =
+ env->GetMethodID(class_satellitePvtBuilder, "setTimeOfClockSeconds",
+ "(J)Landroid/location/SatellitePvt$Builder;");
+ method_satellitePvtBuilderSetTimeOfEphemeris =
+ env->GetMethodID(class_satellitePvtBuilder, "setTimeOfEphemerisSeconds",
+ "(J)Landroid/location/SatellitePvt$Builder;");
+ method_satellitePvtBuilderSetIssueOfDataClock =
+ env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataClock",
+ "(I)Landroid/location/SatellitePvt$Builder;");
+ method_satellitePvtBuilderSetIssueOfDataEphemeris =
+ env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataEphemeris",
+ "(I)Landroid/location/SatellitePvt$Builder;");
+ method_satellitePvtBuilderSetEphemerisSource =
+ env->GetMethodID(class_satellitePvtBuilder, "setEphemerisSource",
+ "(I)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderBuild = env->GetMethodID(class_satellitePvtBuilder, "build",
"()Landroid/location/SatellitePvt;");
@@ -429,6 +449,24 @@ void GnssMeasurementCallbackAidl::translateSingleGnssMeasurement(JNIEnv* env,
satellitePvt.tropoDelayMeters);
}
+ if (this->getInterfaceVersion() >= 2) {
+ callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+ method_satellitePvtBuilderSetTimeOfClock,
+ satellitePvt.timeOfClockSeconds);
+ callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+ method_satellitePvtBuilderSetTimeOfEphemeris,
+ satellitePvt.timeOfEphemerisSeconds);
+ callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+ method_satellitePvtBuilderSetIssueOfDataClock,
+ satellitePvt.issueOfDataClock);
+ callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+ method_satellitePvtBuilderSetIssueOfDataEphemeris,
+ satellitePvt.issueOfDataEphemeris);
+ callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+ method_satellitePvtBuilderSetEphemerisSource,
+ static_cast<int>(satellitePvt.ephemerisSource));
+ }
+
jobject satellitePvtObject =
env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderBuild);
env->CallVoidMethod(object.get(), method_gnssMeasurementsSetSatellitePvt,
diff --git a/services/core/jni/gnss/GnssMeasurementCallback.h b/services/core/jni/gnss/GnssMeasurementCallback.h
index 17af94939666..c8f1803800b6 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.h
+++ b/services/core/jni/gnss/GnssMeasurementCallback.h
@@ -52,7 +52,7 @@ void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback {
public:
- GnssMeasurementCallbackAidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+ GnssMeasurementCallbackAidl() : mCallbacksObj(getCallbacksObj()) {}
android::binder::Status gnssMeasurementCb(const hardware::gnss::GnssData& data) override;
private:
@@ -78,7 +78,7 @@ private:
*/
class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback {
public:
- GnssMeasurementCallbackHidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+ GnssMeasurementCallbackHidl() : mCallbacksObj(getCallbacksObj()) {}
hardware::Return<void> gnssMeasurementCb_2_1(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
hardware::Return<void> gnssMeasurementCb_2_0(
@@ -109,23 +109,22 @@ private:
class GnssMeasurementCallback {
public:
- GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+ GnssMeasurementCallback() {}
sp<GnssMeasurementCallbackAidl> getAidl() {
if (callbackAidl == nullptr) {
- callbackAidl = sp<GnssMeasurementCallbackAidl>::make(mCallbacksObj);
+ callbackAidl = sp<GnssMeasurementCallbackAidl>::make();
}
return callbackAidl;
}
sp<GnssMeasurementCallbackHidl> getHidl() {
if (callbackHidl == nullptr) {
- callbackHidl = sp<GnssMeasurementCallbackHidl>::make(mCallbacksObj);
+ callbackHidl = sp<GnssMeasurementCallbackHidl>::make();
}
return callbackHidl;
}
private:
- jobject& mCallbacksObj;
sp<GnssMeasurementCallbackAidl> callbackAidl;
sp<GnssMeasurementCallbackHidl> callbackHidl;
};
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 236f663a9dd0..5388f171854d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -87,6 +87,7 @@ import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN;
import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR;
import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.STATE_USER_SETUP_FINALIZED;
import static android.app.admin.DevicePolicyManager.STATE_USER_UNMANAGED;
import static android.app.admin.DevicePolicyManager.STATUS_ACCOUNTS_NOT_EMPTY;
import static android.app.admin.DevicePolicyManager.STATUS_CANNOT_ADD_MANAGED_PROFILE;
@@ -9183,10 +9184,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
- public void setUserProvisioningState(int newState, int userHandle) {
+ public void setUserProvisioningState(int newState, int userId) {
if (!mHasFeature) {
logMissingFeatureAction("Cannot set provisioning state " + newState + " for user "
- + userHandle);
+ + userId);
return;
}
@@ -9196,12 +9197,24 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity();
final long id = mInjector.binderClearCallingIdentity();
try {
- if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle)
- && getManagedUserId(userHandle) == -1
- && newState != STATE_USER_UNMANAGED) {
- // No managed device, user or profile, so setting provisioning state makes no sense.
- throw new IllegalStateException("Not allowed to change provisioning state unless a "
- + "device or profile owner is set.");
+ int deviceOwnerUserId = mOwners.getDeviceOwnerUserId();
+ // NOTE: multiple if statements are nested below so it can log more info on error
+ if (userId != deviceOwnerUserId) {
+ boolean hasProfileOwner = mOwners.hasProfileOwner(userId);
+ if (!hasProfileOwner) {
+ int managedUserId = getManagedUserId(userId);
+ if (managedUserId == -1 && newState != STATE_USER_UNMANAGED) {
+ // No managed device, user or profile, so setting provisioning state makes
+ // no sense.
+ String error = "Not allowed to change provisioning state unless a "
+ + "device or profile owner is set.";
+ Slogf.w(LOG_TAG, "setUserProvisioningState(newState=%d, userId=%d) failed: "
+ + "deviceOwnerId=%d, hasProfileOwner=%b, managedUserId=%d, err=%s",
+ newState, userId, deviceOwnerUserId, hasProfileOwner,
+ managedUserId, error);
+ throw new IllegalStateException(error);
+ }
+ }
}
synchronized (getLockObject()) {
@@ -9211,9 +9224,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (isAdb(caller)) {
// ADB shell can only move directly from un-managed to finalized as part of
// directly setting profile-owner or device-owner.
- if (getUserProvisioningState(userHandle)
+ if (getUserProvisioningState(userId)
!= DevicePolicyManager.STATE_USER_UNMANAGED
- || newState != DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+ || newState != STATE_USER_SETUP_FINALIZED) {
throw new IllegalStateException("Not allowed to change provisioning state "
+ "unless current provisioning state is unmanaged, and new state"
+ "is finalized.");
@@ -9221,14 +9234,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
transitionCheckNeeded = false;
}
- final DevicePolicyData policyData = getUserData(userHandle);
+ final DevicePolicyData policyData = getUserData(userId);
if (transitionCheckNeeded) {
// Optional state transition check for non-ADB case.
checkUserProvisioningStateTransition(policyData.mUserProvisioningState,
newState);
}
policyData.mUserProvisioningState = newState;
- saveSettingsLocked(userHandle);
+ saveSettingsLocked(userId);
}
} finally {
mInjector.binderRestoreCallingIdentity(id);
@@ -9247,7 +9260,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
case DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE:
case DevicePolicyManager.STATE_USER_SETUP_COMPLETE:
// Can only move to finalized from these states.
- if (newState == DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+ if (newState == STATE_USER_SETUP_FINALIZED) {
return;
}
break;
@@ -9259,7 +9272,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return;
}
break;
- case DevicePolicyManager.STATE_USER_SETUP_FINALIZED:
+ case STATE_USER_SETUP_FINALIZED:
// Cannot transition out of finalized.
break;
case DevicePolicyManager.STATE_USER_PROFILE_FINALIZED:
@@ -18080,7 +18093,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ || (hasCallingOrSelfPermission(permission.PROVISION_DEMO_DEVICE)
+ && provisioningParams.isDemoDevice()));
provisioningParams.logParams(callerPackage);
@@ -18117,8 +18132,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
disallowAddUser();
- setAdminCanGrantSensorsPermissionForUserUnchecked(deviceOwnerUserId,
- provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+ setAdminCanGrantSensorsPermissionForUserUnchecked(
+ deviceOwnerUserId, provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+ setDemoDeviceStateUnchecked(deviceOwnerUserId, provisioningParams.isDemoDevice());
onProvisionFullyManagedDeviceCompleted(provisioningParams);
sendProvisioningCompletedBroadcast(
deviceOwnerUserId,
@@ -18317,6 +18333,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ private void setDemoDeviceStateUnchecked(@UserIdInt int userId, boolean isDemoDevice) {
+ Slogf.d(LOG_TAG, "setDemoDeviceStateUnchecked(%d, %b)",
+ userId, isDemoDevice);
+ if (!isDemoDevice) {
+ return;
+ }
+ synchronized (getLockObject()) {
+ mInjector.settingsGlobalPutStringForUser(
+ Settings.Global.DEVICE_DEMO_MODE, Integer.toString(/* value= */ 1), userId);
+ }
+ setUserProvisioningState(STATE_USER_SETUP_FINALIZED, userId);
+ }
+
private void updateAdminCanGrantSensorsPermissionCache(@UserIdInt int userId) {
synchronized (getLockObject()) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4ff53ead700e..fa2850a5157d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -41,6 +41,7 @@ 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;
@@ -214,8 +215,6 @@ import com.android.server.wm.WindowManagerService;
import dalvik.system.VMRuntime;
-import com.google.android.startop.iorap.IorapForwardingService;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -1227,12 +1226,15 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(domainVerificationService);
t.traceEnd();
+ IPackageManager iPackageManager;
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
- mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
- domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,
- mOnlyCore);
+ Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
+ mSystemContext, installer, domainVerificationService,
+ mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+ mPackageManagerService = pmsPair.first;
+ iPackageManager = pmsPair.second;
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
@@ -1240,7 +1242,7 @@ public final class SystemServer implements Dumpable {
// 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(mPackageManagerService);
+ SystemServerDexLoadReporter.configureSystemServerDexReporter(iPackageManager);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
@@ -1645,10 +1647,6 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(PinnerService.class);
t.traceEnd();
- t.traceBegin("IorapForwardingService");
- mSystemServiceManager.startService(IorapForwardingService.class);
- t.traceEnd();
-
if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) {
t.traceBegin("ProfcollectForwardingService");
mSystemServiceManager.startService(ProfcollectForwardingService.class);
diff --git a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
index b7f8c00896d4..8a9845b1c2d2 100644
--- a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
@@ -16,6 +16,10 @@
package com.android.server.backup;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+
import static com.android.server.backup.testing.TransportData.genericTransport;
import static com.android.server.backup.testing.TransportTestUtils.mockTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager;
@@ -312,6 +316,86 @@ public class TransportManagerTest {
}
@Test
+ public void testOnPackageChanged_whenPackageChanged_packageDisabledUnregistersTransport()
+ throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+ reset(mListener);
+
+ mContext.getPackageManager()
+ .setApplicationEnabledSetting(
+ PACKAGE_A,
+ Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED),
+ 0 /*flags*/);
+ transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+ assertRegisteredTransports(transportManager, singletonList(mTransportB1));
+ verify(mListener, never()).onTransportRegistered(any(), any());
+ }
+
+ @Test
+ public void testOnPackageChanged_whenPackageChanged_packageEnabledRegistersTransport()
+ throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+ reset(mListener);
+
+ mContext.getPackageManager()
+ .setApplicationEnabledSetting(
+ PACKAGE_A,
+ Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED),
+ 0 /*flags*/);
+ transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+ assertRegisteredTransports(transportManager, singletonList(mTransportB1));
+ verify(mListener, never()).onTransportRegistered(any(), any());
+
+ mContext.getPackageManager()
+ .setApplicationEnabledSetting(
+ PACKAGE_A,
+ Integer.valueOf(COMPONENT_ENABLED_STATE_ENABLED),
+ 0 /*flags*/);
+ transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+ assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+ verify(mListener)
+ .onTransportRegistered(mTransportA1.transportName, mTransportA1.transportDirName);
+ }
+
+ @Test
+ public void testOnPackageChanged_whenPackageChanged_unknownComponentStateIsIgnored()
+ throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+ reset(mListener);
+
+ mContext.getPackageManager()
+ .setApplicationEnabledSetting(
+ PACKAGE_A,
+ Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT),
+ 0 /*flags*/);
+ transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+ assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+ verify(mListener, never()).onTransportRegistered(any(), any());
+ }
+
+ @Test
+ public void testOnPackageChanged_whenPackageChanged_unknownPackageExceptionIsIgnored()
+ throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+ reset(mListener);
+
+ // empty packageName triggers Robolectric ApplicationPackageManager to throw
+ // exception as if package does not exist.
+ transportManager.onPackageChanged("", "");
+
+ assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+ verify(mListener, never()).onTransportRegistered(any(), any());
+ }
+
+ @Test
public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception {
TransportManager transportManager =
createTransportManagerWithRegisteredTransports(null, mTransportA1);
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
index aea36e555ad7..4a9948668bc4 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
@@ -16,6 +16,7 @@
package com.android.server.testing.shadows;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.NameNotFoundException;
import android.app.ApplicationPackageManager;
@@ -44,6 +45,7 @@ public class ShadowApplicationPackageManager
private static final List<PackageInfo> sInstalledPackages = new ArrayList<>();
private static final Map<String, Integer> sPackageUids = new ArrayMap<>();
private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>();
+ private static final Map<String, Integer> sPackageAppEnabledStates = new ArrayMap<>();
/**
* Registers the package {@code packageName} to be returned when invoking {@link
@@ -53,6 +55,7 @@ public class ShadowApplicationPackageManager
public static void addInstalledPackage(String packageName, PackageInfo packageInfo) {
sPackageInfos.put(packageName, packageInfo);
sInstalledPackages.add(packageInfo);
+ sPackageAppEnabledStates.put(packageName, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT));
}
/**
@@ -77,6 +80,22 @@ public class ShadowApplicationPackageManager
}
@Override
+ protected int getApplicationEnabledSetting(String packageName) {
+ if (packageName.isEmpty()) {
+ throw new IllegalArgumentException("Robo: Package '' does not exist.");
+ }
+ if (!sPackageAppEnabledStates.containsKey(packageName)) {
+ return COMPONENT_ENABLED_STATE_DEFAULT;
+ }
+ return sPackageAppEnabledStates.get(packageName);
+ }
+
+ @Override
+ protected void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+ sPackageAppEnabledStates.put(packageName, Integer.valueOf(newState)); // flags unused here.
+ }
+
+ @Override
protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
throws NameNotFoundException {
if (!sPackageInfos.containsKey(packageName)) {
@@ -115,6 +134,7 @@ public class ShadowApplicationPackageManager
public static void reset() {
sPackageInfos.clear();
sInstalledPackages.clear();
+ sPackageAppEnabledStates.clear();
org.robolectric.shadows.ShadowApplicationPackageManager.reset();
}
}
diff --git a/services/startop/Android.bp b/services/startop/Android.bp
deleted file mode 100644
index c56c463d0168..000000000000
--- a/services/startop/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package {
- // 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
- // SPDX-license-identifier-MIT
- // SPDX-license-identifier-Unicode-DFS
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library_static {
- name: "services.startop",
- defaults: ["platform_service_defaults"],
-
- static_libs: [
- // frameworks/base/startop/iorap
- "services.startop.iorap",
- ],
-}
diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
index dcc461be0015..7017440a86bb 100644
--- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
+++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
@@ -221,11 +221,14 @@ class PackageManagerComponentLabelIconOverrideTest {
@After
fun verifyExpectedResult() {
assertServiceInitialized() ?: return
- if (params.componentName != null) {
- val activityInfo = service.getActivityInfo(params.componentName, 0, userId)
- if (activityInfo != null) {
- assertThat(activityInfo.nonLocalizedLabel).isEqualTo(params.expectedLabel)
- assertThat(activityInfo.icon).isEqualTo(params.expectedIcon)
+ if (params.componentName != null && params.result !is Result.Exception) {
+ // Suppress so that failures in @After don't override the actual test failure
+ @Suppress("UNNECESSARY_SAFE_CALL")
+ service?.let {
+ val activityInfo = it.snapshotComputer()
+ .getActivityInfo(params.componentName, 0, userId)
+ assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(params.expectedLabel)
+ assertThat(activityInfo?.icon).isEqualTo(params.expectedIcon)
}
}
}
@@ -237,9 +240,12 @@ class PackageManagerComponentLabelIconOverrideTest {
Result.Changed, Result.ChangedWithoutNotify -> {
// Suppress so that failures in @After don't override the actual test failure
@Suppress("UNNECESSARY_SAFE_CALL")
- val activityInfo = service?.getActivityInfo(params.componentName, 0, userIdDifferent)
- assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL)
- assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON)
+ service?.let {
+ val activityInfo = it.snapshotComputer()
+ ?.getActivityInfo(params.componentName, 0, userIdDifferent)
+ assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL)
+ assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON)
+ }
}
Result.NotChanged, is Result.Exception -> {}
}.run { /*exhaust*/ }
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index b5ad459d29f7..784f732ba3b1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -754,6 +754,57 @@ public class LocalDisplayAdapterTest {
verify(mMockedBacklight, never()).setBrightness(anyFloat());
}
+ @Test
+ public void testGetSystemPreferredDisplayMode() throws Exception {
+ SurfaceControl.DisplayMode displayMode1 = createFakeDisplayMode(0, 1920, 1080, 60f);
+ // preferred mode
+ SurfaceControl.DisplayMode displayMode2 = createFakeDisplayMode(1, 3840, 2160, 60f);
+
+ SurfaceControl.DisplayMode[] modes =
+ new SurfaceControl.DisplayMode[]{displayMode1, displayMode2};
+ FakeDisplay display = new FakeDisplay(PORT_A, modes, 0, 1);
+ setUpDisplay(display);
+ updateAvailableDisplays();
+ mAdapter.registerLocked();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+ assertThat(mListener.changedDisplays).isEmpty();
+
+ DisplayDeviceInfo displayDeviceInfo = mListener.addedDisplays.get(
+ 0).getDisplayDeviceInfoLocked();
+
+ assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
+
+ Display.Mode defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
+ assertThat(matches(defaultMode, displayMode2)).isTrue();
+
+ // Change the display and add new preferred mode
+ SurfaceControl.DisplayMode addedDisplayInfo = createFakeDisplayMode(2, 2340, 1080, 60f);
+ modes = new SurfaceControl.DisplayMode[]{displayMode1, displayMode2, addedDisplayInfo};
+ display.dynamicInfo.supportedDisplayModes = modes;
+ display.dynamicInfo.preferredBootDisplayMode = 2;
+ setUpDisplay(display);
+ mInjector.getTransmitter().sendHotplug(display, /* connected */ true);
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ assertTrue(mListener.traversalRequested);
+ assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+ assertThat(mListener.changedDisplays.size()).isEqualTo(1);
+
+ DisplayDevice displayDevice = mListener.changedDisplays.get(0);
+ displayDevice.applyPendingDisplayDeviceInfoChangesLocked();
+ displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked();
+
+ assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
+ assertModeIsSupported(displayDeviceInfo.supportedModes, displayMode1);
+ assertModeIsSupported(displayDeviceInfo.supportedModes, displayMode2);
+ assertModeIsSupported(displayDeviceInfo.supportedModes, addedDisplayInfo);
+
+ assertThat(matches(displayDevice.getSystemPreferredDisplayModeLocked(), addedDisplayInfo))
+ .isTrue();
+ }
+
private void assertDisplayDpi(DisplayDeviceInfo info, int expectedPort,
float expectedXdpi,
float expectedYDpi,
@@ -831,6 +882,16 @@ public class LocalDisplayAdapterTest {
dynamicInfo.supportedDisplayModes = modes;
dynamicInfo.activeDisplayModeId = activeMode;
}
+
+ private FakeDisplay(int port, SurfaceControl.DisplayMode[] modes, int activeMode,
+ int preferredMode) {
+ address = createDisplayAddress(port);
+ info = createFakeDisplayInfo();
+ dynamicInfo.supportedDisplayModes = modes;
+ dynamicInfo.activeDisplayModeId = activeMode;
+ dynamicInfo.preferredBootDisplayMode = preferredMode;
+ }
+
}
private void setUpDisplay(FakeDisplay display) {
@@ -843,6 +904,7 @@ public class LocalDisplayAdapterTest {
.thenReturn(display.dynamicInfo);
when(mSurfaceControlProxy.getDesiredDisplayModeSpecs(display.token))
.thenReturn(display.desiredDisplayModeSpecs);
+ when(mSurfaceControlProxy.getBootDisplayModeSupport()).thenReturn(true);
}
private void updateAvailableDisplays() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
index ccfeb4c9df51..fbbb814388f7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
@@ -74,6 +74,10 @@ class PackageFreezerTest {
assertThat(assertFailsWith(exceptionClass, block).message).contains(message)
}
+ private fun checkPackageStartable() {
+ pms.checkPackageStartable(pms.snapshotComputer(), TEST_PACKAGE, TEST_USER_ID)
+ }
+
@Before
@Throws(Exception::class)
fun setup() {
@@ -89,11 +93,11 @@ class PackageFreezerTest {
.killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
freezer.close()
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
@Test
@@ -104,16 +108,16 @@ class PackageFreezerTest {
.killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
freezer1.close()
assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
freezer2.close()
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
@Test
@@ -123,13 +127,13 @@ class PackageFreezerTest {
.killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
freezer = null
System.gc()
System.runFinalization()
- pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+ checkPackageStartable()
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
index a6c7bfb456be..13199032a223 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
@@ -107,7 +107,7 @@ class PackageManagerServiceHibernationTests {
whenever(appHibernationManager.isHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(true)
- pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
+ pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false, TEST_USER_ID)
TestableLooper.get(this).processAllMessages()
@@ -133,7 +133,8 @@ class PackageManagerServiceHibernationTests {
.thenReturn(true)
try {
- pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
+ pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false,
+ TEST_USER_ID)
TestableLooper.get(this).processAllMessages()
} catch (e: Exception) {
Assert.fail("Method throws exception when AppHibernationManager is not ready.\n$e")
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index fefc42549688..86b6da0faad5 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -28,7 +28,9 @@ import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EV
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.verify;
@@ -70,6 +72,8 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class LogicalDisplayMapperTest {
private static int sUniqueTestDisplayId = 0;
+ private static final int DEVICE_STATE_CLOSED = 0;
+ private static final int DEVICE_STATE_OPEN = 2;
private DisplayDeviceRepository mDisplayDeviceRepo;
private LogicalDisplayMapper mLogicalDisplayMapper;
@@ -113,6 +117,7 @@ public class LogicalDisplayMapperTest {
mPowerManager = new PowerManager(mContextMock, mIPowerManagerMock, mIThermalServiceMock,
null);
+
when(mContextMock.getSystemServiceName(PowerManager.class))
.thenReturn(Context.POWER_SERVICE);
when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
@@ -120,6 +125,12 @@ public class LogicalDisplayMapperTest {
when(mResourcesMock.getBoolean(
com.android.internal.R.bool.config_supportsConcurrentInternalDisplays))
.thenReturn(true);
+ when(mResourcesMock.getIntArray(
+ com.android.internal.R.array.config_deviceStatesOnWhichToWakeUp))
+ .thenReturn(new int[]{1, 2});
+ when(mResourcesMock.getIntArray(
+ com.android.internal.R.array.config_deviceStatesOnWhichToSleep))
+ .thenReturn(new int[]{0});
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
@@ -312,6 +323,49 @@ public class LogicalDisplayMapperTest {
mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
}
+ @Test
+ public void testDeviceShouldBeWoken() {
+ assertTrue(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_OPEN,
+ DEVICE_STATE_CLOSED,
+ /* isInteractive= */false,
+ /* isBootCompleted= */true));
+ }
+
+ @Test
+ public void testDeviceShouldNotBeWoken() {
+ assertFalse(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_CLOSED,
+ DEVICE_STATE_OPEN,
+ /* isInteractive= */false,
+ /* isBootCompleted= */true));
+ }
+
+ @Test
+ public void testDeviceShouldBePutToSleep() {
+ assertTrue(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
+ DEVICE_STATE_OPEN,
+ /* isOverrideActive= */false,
+ /* isInteractive= */true,
+ /* isBootCompleted= */true));
+ }
+
+ @Test
+ public void testDeviceShouldNotBePutToSleep() {
+ assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_OPEN,
+ DEVICE_STATE_CLOSED,
+ /* isOverrideActive= */false,
+ /* isInteractive= */true,
+ /* isBootCompleted= */true));
+ }
+
+ @Test
+ public void testDeviceShouldNotBePutToSleepDifferentBaseState() {
+ assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
+ DEVICE_STATE_OPEN,
+ /* isOverrideActive= */true,
+ /* isInteractive= */true,
+ /* isBootCompleted= */true));
+ }
+
/////////////////
// Helper Methods
/////////////////
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index a9812ab9bb03..d104871f488a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -89,6 +89,7 @@ public class HdmiCecLocalDeviceTvTest {
private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
private int mTvPhysicalAddress;
private int mTvLogicalAddress;
+ private boolean mWokenUp;
@Mock
private AudioManager mAudioManager;
@@ -104,6 +105,11 @@ public class HdmiCecLocalDeviceTvTest {
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
Collections.emptyList()) {
@Override
+ void wakeUp() {
+ mWokenUp = true;
+ super.wakeUp();
+ }
+ @Override
boolean isControlEnabled() {
return true;
}
@@ -308,6 +314,22 @@ public class HdmiCecLocalDeviceTvTest {
}
@Test
+ public void handleTextViewOn_Dreaming() {
+ mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
+ HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED);
+ mTestLooper.dispatchAll();
+ mPowerManager.setInteractive(true);
+ mWokenUp = false;
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
+ mTvLogicalAddress);
+ assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
+ mTestLooper.dispatchAll();
+ assertThat(mPowerManager.isInteractive()).isTrue();
+ assertThat(mWokenUp).isTrue();
+ }
+
+ @Test
public void tvSendStandbyOnSleep_Enabled() {
mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP,
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
index 5185e15a8557..db602ca83f30 100644
--- a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -98,11 +98,8 @@ public class SystemAppUpdateTrackerTest {
private ActivityTaskManagerInternal mMockActivityTaskManager;
@Mock
private ActivityManagerInternal mMockActivityManager;
- @Mock
- private LocaleManagerBackupHelper mMockLocaleManagerBackupHelper;
- @Mock
- PackageMonitor mMockPackageMonitor;
+ PackageMonitor mPackageMonitor;
private LocaleManagerService mLocaleManagerService;
// Object under test.
@@ -114,11 +111,14 @@ public class SystemAppUpdateTrackerTest {
mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
mMockActivityManager = mock(ActivityManagerInternal.class);
mMockPackageManagerInternal = mock(PackageManagerInternal.class);
- mMockPackageMonitor = mock(PackageMonitor.class);
- mMockLocaleManagerBackupHelper = mock(ShadowLocaleManagerBackupHelper.class);
+ LocaleManagerBackupHelper mockLocaleManagerBackupHelper =
+ mock(ShadowLocaleManagerBackupHelper.class);
+ // PackageMonitor is not needed in LocaleManagerService for these tests hence it is
+ // passed as null.
mLocaleManagerService = new LocaleManagerService(mMockContext,
mMockActivityTaskManager, mMockActivityManager,
- mMockPackageManagerInternal, mMockLocaleManagerBackupHelper, mMockPackageMonitor);
+ mMockPackageManagerInternal, mockLocaleManagerBackupHelper,
+ /* mPackageMonitor= */ null);
doReturn(DEFAULT_USER_ID).when(mMockActivityManager)
.handleIncomingUser(anyInt(), anyInt(), eq(DEFAULT_USER_ID), anyBoolean(), anyInt(),
@@ -134,6 +134,9 @@ public class SystemAppUpdateTrackerTest {
mSystemAppUpdateTracker = new SystemAppUpdateTracker(mMockContext,
mLocaleManagerService, mStoragefile);
+
+ mPackageMonitor = new LocaleManagerServicePackageMonitor(
+ mockLocaleManagerBackupHelper, mSystemAppUpdateTracker);
}
@After
@@ -148,7 +151,7 @@ public class SystemAppUpdateTrackerTest {
.when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
// Updates the app once so that it writes to the file.
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
Binder.getCallingUid());
// Clear the in-memory data of updated apps
mSystemAppUpdateTracker.getUpdatedApps().clear();
@@ -167,7 +170,7 @@ public class SystemAppUpdateTrackerTest {
DEFAULT_LOCALES)).when(mMockActivityTaskManager)
.getApplicationConfig(anyString(), anyInt());
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
Binder.getCallingUid());
assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
@@ -186,7 +189,7 @@ public class SystemAppUpdateTrackerTest {
.getApplicationConfig(anyString(), anyInt());
// first update
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
Binder.getCallingUid());
assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
@@ -195,7 +198,7 @@ public class SystemAppUpdateTrackerTest {
verifyStorageFileContents(expectedAppList);
// second update
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
Binder.getCallingUid());
// getApplicationLocales should be invoked only once on the first update.
verify(mMockActivityTaskManager, times(1))
@@ -212,7 +215,7 @@ public class SystemAppUpdateTrackerTest {
/* isUpdatedSystemApp = */false))
.when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_2), any());
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_2,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_2,
Binder.getCallingUid());
assertTrue(!mSystemAppUpdateTracker.getUpdatedApps().contains(DEFAULT_PACKAGE_NAME_2));
@@ -231,7 +234,7 @@ public class SystemAppUpdateTrackerTest {
.when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
doReturn(null).when(mMockPackageManager).getInstallSourceInfo(anyString());
- mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+ mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
Binder.getCallingUid());
// getApplicationLocales should be never be invoked if not installer is not present.
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index 3d21b74825f0..b37e94aaecac 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -20,6 +20,10 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -68,12 +72,17 @@ public class PackageInstallerSessionTest {
@Mock
PackageManagerService mMockPackageManagerInternal;
+ @Mock
+ Computer mSnapshot;
+
@Before
public void setUp() throws Exception {
mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest");
mSessionsFile = new AtomicFile(
new File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session");
MockitoAnnotations.initMocks(this);
+ when(mSnapshot.getPackageUid(anyString(), anyLong(), anyInt())).thenReturn(0);
+ when(mMockPackageManagerInternal.snapshotComputer()).thenReturn(mSnapshot);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 401cd7f0b67e..c7b5547170d0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1079,6 +1079,19 @@ public final class UserManagerTest {
}
@Test
+ public void testGetUserName_shouldReturnTranslatedTextForNullNamedGuestUser() throws Exception {
+ UserInfo guestWithNullName = createUser(null, UserManager.USER_TYPE_FULL_GUEST, 0);
+ assertThat(guestWithNullName).isNotNull();
+
+ UserManager um = (UserManager) mContext.createPackageContextAsUser(
+ "android", 0, guestWithNullName.getUserHandle())
+ .getSystemService(Context.USER_SERVICE);
+
+ assertThat(um.getUserName()).isEqualTo(
+ mContext.getString(com.android.internal.R.string.guest_name));
+ }
+
+ @Test
public void testGetUserIcon_withContextUserId() throws Exception {
assumeManagedUsersSupported();
final int primaryUserId = mUserManager.getPrimaryUser().id;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 3cda2a554e48..ec16188bfc1d 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -288,7 +288,7 @@ public class VibrationSettingsTest {
}
@Test
- public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneOnly() {
+ public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneAndNotification() {
// Vibrating settings on are overruled by ringer mode.
setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
@@ -296,7 +296,7 @@ public class VibrationSettingsTest {
setRingerMode(AudioManager.RINGER_MODE_SILENT);
for (int usage : ALL_USAGES) {
- if (usage == USAGE_RINGTONE) {
+ if (usage == USAGE_RINGTONE || usage == USAGE_NOTIFICATION) {
assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_FOR_RINGER_MODE);
} else {
assertVibrationNotIgnoredForUsage(usage);
@@ -305,6 +305,16 @@ public class VibrationSettingsTest {
}
@Test
+ public void shouldIgnoreVibration_withRingerModeSilentAndBypassFlag_allowsAllVibrations() {
+ setRingerMode(AudioManager.RINGER_MODE_SILENT);
+
+ for (int usage : ALL_USAGES) {
+ assertVibrationNotIgnoredForUsageAndFlags(usage,
+ VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
+ }
+ }
+
+ @Test
public void shouldIgnoreVibration_withRingerModeVibrate_allowsAllVibrations() {
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index e46e28199d5a..92736c517782 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -1136,19 +1136,23 @@ public class VibratorManagerServiceTest {
}
@Test
- public void onExternalVibration_setsExternalControl() {
+ public void onExternalVibration_setsExternalControl() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
createSystemReadyService();
+ IBinder binderToken = mock(IBinder.class);
ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_ATTRS,
- mock(IExternalVibrationController.class));
+ mock(IExternalVibrationController.class), binderToken);
int scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
mExternalVibratorService.onExternalVibrationStop(externalVibration);
assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
assertEquals(Arrays.asList(false, true, false),
mVibratorProviders.get(1).getExternalControlStates());
+
+ verify(binderToken).linkToDeath(any(), eq(0));
+ verify(binderToken).unlinkToDeath(any(), eq(0));
}
@Test
@@ -1160,17 +1164,19 @@ public class VibratorManagerServiceTest {
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
createSystemReadyService();
+ IBinder firstToken = mock(IBinder.class);
+ IBinder secondToken = mock(IBinder.class);
IExternalVibrationController firstController = mock(IExternalVibrationController.class);
IExternalVibrationController secondController = mock(IExternalVibrationController.class);
ExternalVibration firstVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_ATTRS,
- firstController);
+ firstController, firstToken);
int firstScale = mExternalVibratorService.onExternalVibrationStart(firstVibration);
AudioAttributes ringtoneAudioAttrs = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.build();
ExternalVibration secondVibration = new ExternalVibration(UID, PACKAGE_NAME,
- ringtoneAudioAttrs, secondController);
+ ringtoneAudioAttrs, secondController, secondToken);
int secondScale = mExternalVibratorService.onExternalVibrationStart(secondVibration);
assertNotEquals(IExternalVibratorService.SCALE_MUTE, firstScale);
@@ -1180,6 +1186,17 @@ public class VibratorManagerServiceTest {
// Set external control called only once.
assertEquals(Arrays.asList(false, true),
mVibratorProviders.get(1).getExternalControlStates());
+
+ mExternalVibratorService.onExternalVibrationStop(secondVibration);
+ mExternalVibratorService.onExternalVibrationStop(firstVibration);
+ assertEquals(Arrays.asList(false, true, false),
+ mVibratorProviders.get(1).getExternalControlStates());
+
+ verify(firstToken).linkToDeath(any(), eq(0));
+ verify(firstToken).unlinkToDeath(any(), eq(0));
+
+ verify(secondToken).linkToDeath(any(), eq(0));
+ verify(secondToken).unlinkToDeath(any(), eq(0));
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 71f8b8de032b..d752322f567a 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -18,6 +18,7 @@ package com.android.server.notification;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.Notification.FLAG_AUTO_CANCEL;
@@ -432,8 +433,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
- when(mPermissionPolicyInternal.canShowPermissionPromptForTask(
- any(ActivityManager.RecentTaskInfo.class))).thenReturn(false);
+ when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt()))
+ .thenReturn(INVALID_TASK_ID);
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
@@ -971,8 +972,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCreateNotificationChannels_FirstChannelWithFgndTaskStartsPermDialog()
throws Exception {
- when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
- ActivityManager.RecentTaskInfo.class))).thenReturn(true);
+ when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
final NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
mBinderService.createNotificationChannels(PKG_NO_CHANNELS,
@@ -985,8 +985,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCreateNotificationChannels_SecondChannelWithFgndTaskDoesntStartPermDialog()
throws Exception {
- when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
- ActivityManager.RecentTaskInfo.class))).thenReturn(true);
+ when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
assertTrue(mBinderService.getNumNotificationChannelsForPackage(PKG, mUid, true) > 0);
final NotificationChannel channel =
@@ -1001,8 +1000,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCreateNotificationChannels_FirstChannelWithBgndTaskDoesntStartPermDialog()
throws Exception {
reset(mPermissionPolicyInternal);
- when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
- ActivityManager.RecentTaskInfo.class))).thenReturn(false);
+ when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
final NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index a24ba0d1e1c2..50151bfb7191 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -89,6 +89,10 @@ public class PermissionHelperTest extends UiServiceTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true);
+ PackageInfo testPkgInfo = new PackageInfo();
+ testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS };
+ when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
+ .thenReturn(testPkgInfo);
}
// TODO (b/194833441): Remove when the migration is enabled
@@ -384,6 +388,22 @@ public class PermissionHelperTest extends UiServiceTestCase {
}
@Test
+ public void testSetNotificationPermission_doesntRequestNotChanged() throws Exception {
+ when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+ .thenReturn(PERMISSION_GRANTED);
+ PackageInfo testPkgInfo = new PackageInfo();
+ testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.RECORD_AUDIO };
+ when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
+ .thenReturn(testPkgInfo);
+ mPermissionHelper.setNotificationPermission("pkg", 10, false, false);
+
+ verify(mPmi, never()).checkPermission(
+ eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10));
+ verify(mPermManager, never()).revokeRuntimePermission(
+ eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
+ }
+
+ @Test
public void testIsPermissionFixed() throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 8f1eed89647c..7d5a0d0bf84d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -1870,46 +1870,46 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- USER.getIdentifier()).getList().size());
+ UID_N_MR1).getList().size());
}
@Test
- public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
+ public void testGetChannelsBypassingDnd_noChannelsForUidBypassing()
throws Exception {
- int user = 9;
+ int uid = 222;
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_MAX);
channel.setBypassDnd(true);
mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
}
@Test
public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
- int user = USER.getIdentifier();
+ int uid = UID_N_MR1;
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
NotificationChannel channel1 = new NotificationChannel("id1", "name1",
NotificationManager.IMPORTANCE_MAX);
channel1.setBypassDnd(true);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
// disable group
ncg.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ false);
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
}
@Test
public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
- int user = USER.getIdentifier();
+ int uid = UID_N_MR1;
NotificationChannel channel1 = new NotificationChannel("id1", "name1",
NotificationManager.IMPORTANCE_MAX);
NotificationChannel channel2 = new NotificationChannel("id2", "name2",
@@ -1920,22 +1920,22 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel2.setBypassDnd(true);
channel3.setBypassDnd(true);
// has DND access, so can set bypassDnd attribute
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true);
assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
// setBypassDnd false for some channels
channel1.setBypassDnd(false);
channel2.setBypassDnd(false);
assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
// setBypassDnd false for rest of the channels
channel3.setBypassDnd(false);
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
+ uid).getList().size());
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index abcc8c1e99cb..8ac729e29424 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -121,7 +121,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
// Create a notification record with the people String array as the
// bundled extras, and the numbers ArraySet as additional phone numbers.
- private NotificationRecord getRecordWithPeopleInfo(String[] people,
+ private NotificationRecord getCallRecordWithPeopleInfo(String[] people,
ArraySet<String> numbers) {
// set up notification record
NotificationRecord r = mock(NotificationRecord.class);
@@ -131,6 +131,8 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
when(sbn.getNotification()).thenReturn(notification);
when(r.getSbn()).thenReturn(sbn);
when(r.getPhoneNumbers()).thenReturn(numbers);
+ when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL);
+ when(r.isCategory(CATEGORY_CALL)).thenReturn(true);
return r;
}
@@ -350,11 +352,41 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
}
@Test
+ public void testRepeatCallers_checksPhoneNumbers() {
+ // set up telephony manager behavior
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+ // first, record a phone call from a telephone number
+ String[] callNumber = new String[]{"tel:12345678910"};
+ mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(callNumber, null));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // make sure that a record with the phone number in extras is correctly allowed through
+ NotificationRecord r = getCallRecordWithPeopleInfo(callNumber, null);
+ assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+
+ // make sure that a record with the phone number in the phone numbers array is also
+ // allowed through
+ NotificationRecord r2 = getCallRecordWithPeopleInfo(new String[]{"some_contact_uri"},
+ new ArraySet<>(new String[]{"12345678910"}));
+ assertFalse(mZenModeFiltering.shouldIntercept(
+ ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r2));
+
+ // A record with the phone number in neither of the above should be intercepted
+ NotificationRecord r3 = getCallRecordWithPeopleInfo(new String[]{"tel:10987654321"},
+ new ArraySet<>(new String[]{"15555555555"}));
+ assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r3));
+ }
+
+ @Test
public void testMatchesCallFilter_repeatCallers_directMatch() {
// after calls given an email with an exact string match, make sure that
// matchesCallFilter returns the right thing
String[] mailSource = new String[]{"mailto:hello.world"};
- mZenModeFiltering.recordCall(getRecordWithPeopleInfo(mailSource, null));
+ mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(mailSource, null));
// set up policy to only allow repeat callers
Policy policy = new Policy(
@@ -377,7 +409,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
String[] telSource = new String[]{"tel:+1-617-555-1212"};
- mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
+ mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
// set up policy to only allow repeat callers
Policy policy = new Policy(
@@ -421,7 +453,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
String[] telSource = new String[]{"tel:%2B16175551212"};
- mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
+ mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
// set up policy to only allow repeat callers
Policy policy = new Policy(
@@ -468,7 +500,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
String[] contactSource = new String[]{"content://contacts/lookup/uri-here"};
ArraySet<String> contactNumbers = new ArraySet<>(
new String[]{"1-617-555-1212", "1-617-555-3434"});
- NotificationRecord record = getRecordWithPeopleInfo(contactSource, contactNumbers);
+ NotificationRecord record = getCallRecordWithPeopleInfo(contactSource, contactNumbers);
record.mergePhoneNumbers(contactNumbers);
mZenModeFiltering.recordCall(record);
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
index 75479de26b1d..cf571815b4cb 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
@@ -36,6 +36,9 @@ import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* Test class for {@link KeyCombinationManager}.
*
@@ -47,16 +50,18 @@ import org.junit.Test;
public class KeyCombinationTests {
private KeyCombinationManager mKeyCombinationManager;
- private boolean mAction1Triggered = false;
- private boolean mAction2Triggered = false;
- private boolean mAction3Triggered = false;
+ private final CountDownLatch mAction1Triggered = new CountDownLatch(1);
+ private final CountDownLatch mAction2Triggered = new CountDownLatch(1);
+ private final CountDownLatch mAction3Triggered = new CountDownLatch(1);
private boolean mPreCondition = true;
private static final long SCHEDULE_TIME = 300;
+ private Handler mHandler;
@Before
public void setUp() {
- mKeyCombinationManager = new KeyCombinationManager();
+ mHandler = new Handler(Looper.getMainLooper());
+ mKeyCombinationManager = new KeyCombinationManager(mHandler);
initKeyCombinationRules();
}
@@ -67,7 +72,7 @@ public class KeyCombinationTests {
KEYCODE_POWER) {
@Override
void execute() {
- mAction1Triggered = true;
+ mAction1Triggered.countDown();
}
@Override
@@ -86,12 +91,17 @@ public class KeyCombinationTests {
@Override
void execute() {
- mAction2Triggered = true;
+ mAction2Triggered.countDown();
}
@Override
void cancel() {
}
+
+ @Override
+ long getKeyInterceptDelayMs() {
+ return 0;
+ }
});
// Rule 3 : power + volume_up schedule and trigger action after timeout.
@@ -100,10 +110,9 @@ public class KeyCombinationTests {
final Runnable mAction = new Runnable() {
@Override
public void run() {
- mAction3Triggered = true;
+ mAction3Triggered.countDown();
}
};
- final Handler mHandler = new Handler(Looper.getMainLooper());
@Override
void execute() {
@@ -149,60 +158,74 @@ public class KeyCombinationTests {
}
@Test
- public void testTriggerRule() {
+ public void testTriggerRule() throws InterruptedException {
final long eventTime = SystemClock.uptimeMillis();
pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
- assertTrue(mAction1Triggered);
+ assertTrue(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
- assertTrue(mAction2Triggered);
+ assertTrue(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP, SCHEDULE_TIME + 50);
- assertTrue(mAction3Triggered);
+ assertTrue(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
}
/**
* Nothing should happen if there is no definition.
*/
@Test
- public void testNotTrigger_NoRule() {
+ public void testNotTrigger_NoRule() throws InterruptedException {
final long eventTime = SystemClock.uptimeMillis();
pressKeys(eventTime, KEYCODE_BACK, eventTime, KEYCODE_VOLUME_DOWN);
- assertFalse(mAction1Triggered);
- assertFalse(mAction2Triggered);
- assertFalse(mAction3Triggered);
+ assertFalse(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
+ assertFalse(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
+ assertFalse(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
}
/**
* Nothing should happen if the interval of press time is too long.
*/
@Test
- public void testNotTrigger_Interval() {
+ public void testNotTrigger_Interval() throws InterruptedException {
final long eventTime = SystemClock.uptimeMillis();
final long earlyEventTime = eventTime - 200; // COMBINE_KEY_DELAY_MILLIS = 150;
pressKeys(earlyEventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
- assertFalse(mAction1Triggered);
+ assertFalse(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
}
/**
* Nothing should happen if the condition is false.
*/
@Test
- public void testNotTrigger_Condition() {
+ public void testNotTrigger_Condition() throws InterruptedException {
final long eventTime = SystemClock.uptimeMillis();
// we won't trigger action 2 because the condition is false.
mPreCondition = false;
pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
- assertFalse(mAction2Triggered);
+ assertFalse(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
}
/**
* Nothing should happen if the keys released too early.
*/
@Test
- public void testNotTrigger_EarlyRelease() {
+ public void testNotTrigger_EarlyRelease() throws InterruptedException {
final long eventTime = SystemClock.uptimeMillis();
pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP);
- assertFalse(mAction3Triggered);
+ assertFalse(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
+ }
+
+ /**
+ * The KeyInterceptTimeout should return the max timeout value.
+ */
+ @Test
+ public void testKeyInterceptTimeout() {
+ final long eventTime = SystemClock.uptimeMillis();
+ final KeyEvent firstKeyDown = new KeyEvent(eventTime, eventTime, ACTION_DOWN,
+ KEYCODE_VOLUME_UP, 0 /* repeat */, 0 /* metaState */);
+ // Press KEYCODE_VOLUME_UP would activate rule2 and rule3,
+ // and rule2's intercept delay is 0.
+ mKeyCombinationManager.interceptKey(firstKeyDown, true);
+ assertTrue(mKeyCombinationManager.getKeyInterceptTimeout(KEYCODE_VOLUME_UP) > eventTime);
}
-}
+} \ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/policy/OWNERS b/services/tests/wmtests/src/com/android/server/policy/OWNERS
new file mode 100644
index 000000000000..27891dcf64da
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/policy/OWNERS
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 a89c5a1fbf1f..40ab8eb70c04 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2217,6 +2217,19 @@ public class ActivityRecordTests extends WindowTestsBase {
assertTrue(activity.pictureInPictureArgs.isLaunchIntoPip());
}
+ @Test
+ public void testTransferLaunchCookieWhenFinishing() {
+ final ActivityRecord activity1 = createActivityWithTask();
+ final Binder launchCookie = new Binder();
+ activity1.mLaunchCookie = launchCookie;
+ final ActivityRecord activity2 = createActivityRecord(activity1.getTask());
+ activity1.setState(PAUSED, "test");
+ activity1.makeFinishingLocked();
+
+ assertEquals(launchCookie, activity2.mLaunchCookie);
+ assertNull(activity1.mLaunchCookie);
+ }
+
private void verifyProcessInfoUpdate(ActivityRecord activity, State state,
boolean shouldUpdate, boolean activityChange) {
reset(activity.app);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index 0c8394e75fbc..24ff3f96100a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -41,9 +41,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
@@ -58,8 +60,6 @@ import com.android.internal.app.SuspendedAppActivity;
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult;
import org.junit.After;
import org.junit.Before;
@@ -113,7 +113,7 @@ public class ActivityStartInterceptorTest {
@Mock
private KeyguardManager mKeyguardManager;
@Mock
- private PackageManagerService mPackageManager;
+ private IPackageManager mPackageManager;
@Mock
private ActivityManagerInternal mAmInternal;
@Mock
@@ -126,7 +126,7 @@ public class ActivityStartInterceptorTest {
new SparseArray<>();
@Before
- public void setUp() {
+ public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
mService.mAmInternal = mAmInternal;
mInterceptor = new ActivityStartInterceptor(
@@ -279,7 +279,7 @@ public class ActivityStartInterceptorTest {
}
@Test
- public void testHarmfulAppWarning() {
+ public void testHarmfulAppWarning() throws RemoteException {
// GIVEN the package we're about to launch has a harmful app warning set
when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn("This app is bad");
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 6fe2d337e4a0..f9aa4b17bc2c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -308,12 +308,12 @@ public class ActivityStarterTests extends WindowTestsBase {
}
private ActivityStarter prepareStarter(@Intent.Flags int launchFlags) {
- return prepareStarter(launchFlags, true /* mockGetLaunchStack */, LAUNCH_MULTIPLE);
+ return prepareStarter(launchFlags, true /* mockGetRootTask */, LAUNCH_MULTIPLE);
}
private ActivityStarter prepareStarter(@Intent.Flags int launchFlags,
- boolean mockGetLaunchStack) {
- return prepareStarter(launchFlags, mockGetLaunchStack, LAUNCH_MULTIPLE);
+ boolean mockGetRootTask) {
+ return prepareStarter(launchFlags, mockGetRootTask, LAUNCH_MULTIPLE);
}
private void setupImeWindow() {
@@ -326,20 +326,20 @@ public class ActivityStarterTests extends WindowTestsBase {
* Creates a {@link ActivityStarter} with default parameters and necessary mocks.
*
* @param launchFlags The intent flags to launch activity.
- * @param mockGetLaunchStack Whether to mock {@link RootWindowContainer#getLaunchRootTask} for
+ * @param mockGetRootTask Whether to mock {@link RootWindowContainer#getOrCreateRootTask} for
* always launching to the testing stack. Set to false when allowing
* the activity can be launched to any stack that is decided by real
* implementation.
* @return A {@link ActivityStarter} with default setup.
*/
private ActivityStarter prepareStarter(@Intent.Flags int launchFlags,
- boolean mockGetLaunchStack, int launchMode) {
+ boolean mockGetRootTask, int launchMode) {
// always allow test to start activity.
doReturn(true).when(mSupervisor).checkStartAnyActivityPermission(
any(), any(), any(), anyInt(), anyInt(), anyInt(), any(), any(),
anyBoolean(), anyBoolean(), any(), any(), any());
- if (mockGetLaunchStack) {
+ if (mockGetRootTask) {
// Instrument the stack and task used.
final Task stack = mRootWindowContainer.getDefaultTaskDisplayArea()
.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
@@ -347,9 +347,9 @@ public class ActivityStarterTests extends WindowTestsBase {
// Direct starter to use spy stack.
doReturn(stack).when(mRootWindowContainer)
- .getLaunchRootTask(any(), any(), any(), anyBoolean());
- doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(),
- anyBoolean(), any(), anyInt());
+ .getOrCreateRootTask(any(), any(), any(), anyBoolean());
+ doReturn(stack).when(mRootWindowContainer).getOrCreateRootTask(any(), any(), any(),
+ any(), anyBoolean(), any(), anyInt());
}
// Set up mock package manager internal and make sure no unmocked methods are called
@@ -434,7 +434,7 @@ public class ActivityStarterTests extends WindowTestsBase {
public void testSplitScreenDeliverToTop() {
final ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP,
- false /* mockGetLaunchStack */);
+ false /* mockGetRootTask */);
final Pair<ActivityRecord, ActivityRecord> activities = createActivitiesInSplit();
final ActivityRecord splitPrimaryFocusActivity = activities.first;
final ActivityRecord splitSecondReusableActivity = activities.second;
@@ -790,7 +790,7 @@ public class ActivityStarterTests extends WindowTestsBase {
finishingTopActivity.finishing = true;
// Launch the bottom task of the target root task.
- prepareStarter(FLAG_ACTIVITY_NEW_TASK, false /* mockGetLaunchStack */)
+ prepareStarter(FLAG_ACTIVITY_NEW_TASK, false /* mockGetRootTask */)
.setReason("testBringTaskToFrontWhenFocusedTaskIsFinishing")
.setIntent(activity.intent.addFlags(
FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
@@ -809,7 +809,7 @@ public class ActivityStarterTests extends WindowTestsBase {
@Test
public void testDeliverIntentToTopActivityOfNonTopDisplay() {
final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
- false /* mockGetLaunchStack */);
+ false /* mockGetRootTask */);
// Create a secondary display at bottom.
final TestDisplayContent secondaryDisplay =
@@ -849,7 +849,7 @@ public class ActivityStarterTests extends WindowTestsBase {
@Test
public void testBringTaskToFrontOnSecondaryDisplay() {
final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
- false /* mockGetLaunchStack */);
+ false /* mockGetRootTask */);
// Create a secondary display with an activity.
final TestDisplayContent secondaryDisplay =
@@ -943,7 +943,7 @@ public class ActivityStarterTests extends WindowTestsBase {
@Test
public void testReparentTopFocusedActivityToSecondaryDisplay() {
final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
- false /* mockGetLaunchStack */);
+ false /* mockGetRootTask */);
// Create a secondary display at bottom.
final TestDisplayContent secondaryDisplay = addNewDisplayContentAt(POSITION_BOTTOM);
@@ -1076,7 +1076,7 @@ public class ActivityStarterTests extends WindowTestsBase {
@Test
public void testTargetStackInSplitScreen() {
final ActivityStarter starter =
- prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetLaunchStack */);
+ prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetRootTask */);
final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityOptions options = ActivityOptions.makeBasic();
final ActivityRecord[] outActivity = new ActivityRecord[1];
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 8ada97147dd3..a8571906bb06 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -355,7 +355,8 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
@Test
public void testUpdateSleep() {
doCallRealMethod().when(mWm.mRoot).hasAwakeDisplay();
- mSupervisor.mGoingToSleepWakeLock = mock(PowerManager.WakeLock.class);
+ mSupervisor.mGoingToSleepWakeLock =
+ mSystemServicesTestRule.createStubbedWakeLock(true /* needVerification */);
final Task rootHomeTask = mWm.mRoot.getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
final ActivityRecord homeActivity = new ActivityBuilder(mAtm).setTask(rootHomeTask).build();
final ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
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 2ea7fdaf6348..eb6395b46120 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -36,6 +36,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -422,6 +423,7 @@ public class AppTransitionTests extends WindowTestsBase {
public void testActivityRecordReparentToTaskFragment() {
final ActivityRecord activity = createActivityRecord(mDc);
final SurfaceControl activityLeash = mock(SurfaceControl.class);
+ doNothing().when(activity).setDropInputMode(anyInt());
activity.setVisibility(true);
activity.setSurfaceControl(activityLeash);
final Task task = activity.getTask();
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 ed5ea9c15734..8e990f7763c4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -77,7 +77,6 @@ import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -108,6 +107,7 @@ import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.HardwareBuffer;
import android.hardware.display.VirtualDisplay;
import android.metrics.LogMaker;
import android.os.Binder;
@@ -1370,7 +1370,9 @@ public class DisplayContentTests extends WindowTestsBase {
ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */,
false /* forceUpdate */));
- assertNotNull(mDisplayContent.getAsyncRotationController());
+ final AsyncRotationController asyncRotationController =
+ mDisplayContent.getAsyncRotationController();
+ assertNotNull(asyncRotationController);
assertTrue(mStatusBarWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
assertTrue(mNavBarWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
// Notification shade may have its own view animation in real case so do not fade out it.
@@ -1443,6 +1445,7 @@ public class DisplayContentTests extends WindowTestsBase {
mDisplayContent.setImeLayeringTarget(mAppWindow);
LocalServices.getService(WindowManagerInternal.class).onToggleImeRequested(true /* show */,
app.token, app.token, mDisplayContent.mDisplayId);
+ assertTrue(asyncRotationController.isTargetToken(mImeWindow.mToken));
assertTrue(mImeWindow.mToken.hasFixedRotationTransform());
assertTrue(mImeWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
@@ -1936,12 +1939,10 @@ public class DisplayContentTests extends WindowTestsBase {
// Preparation: Simulate snapshot IME surface.
spyOn(mWm.mTaskSnapshotController);
- doReturn(mock(SurfaceControl.ScreenshotHardwareBuffer.class)).when(
- mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(any());
- final SurfaceControl imeSurface = mock(SurfaceControl.class);
- spyOn(imeSurface);
- doReturn(true).when(imeSurface).isValid();
- doReturn(imeSurface).when(mDisplayContent).createImeSurface(any(), any());
+ SurfaceControl.ScreenshotHardwareBuffer mockHwBuffer = mock(
+ SurfaceControl.ScreenshotHardwareBuffer.class);
+ doReturn(mock(HardwareBuffer.class)).when(mockHwBuffer).getHardwareBuffer();
+ doReturn(mockHwBuffer).when(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(any());
// Preparation: Simulate snapshot Task.
ActivityRecord act1 = createActivityRecord(mDisplayContent);
@@ -1967,21 +1968,18 @@ public class DisplayContentTests extends WindowTestsBase {
final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
appWin2.setHasSurface(true);
assertTrue(appWin2.canBeImeTarget());
- doReturn(true).when(appWin1).isAnimating(PARENTS | TRANSITION,
- ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
+ doReturn(true).when(appWin1).isClosing();
+ doReturn(true).when(appWin1).inAppOrRecentsTransition();
// Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
- // be shown at this time.
- final Transaction t = mDisplayContent.getPendingTransaction();
- spyOn(t);
+ // be attached and shown on the display at this time.
mDisplayContent.computeImeTarget(true);
assertEquals(appWin2, mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
assertTrue(mDisplayContent.shouldImeAttachedToApp());
- verify(mDisplayContent, atLeast(1)).attachAndShowImeScreenshotOnTarget();
+ verify(mDisplayContent, atLeast(1)).showImeScreenshot();
verify(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(appWin1.getTask());
assertNotNull(mDisplayContent.mImeScreenshot);
- verify(t).show(mDisplayContent.mImeScreenshot);
}
@UseTestDisplay(addWindows = {W_INPUT_METHOD}, addAllCommonWindows = true)
@@ -2388,19 +2386,18 @@ public class DisplayContentTests extends WindowTestsBase {
w2.setKeepClearAreas(Arrays.asList(rect2), Collections.emptyList());
// No keep clear areas on display, because the windows are not visible
- assertEquals(Arrays.asList(), mDisplayContent.getKeepClearAreas());
+ assertEquals(Collections.emptySet(), mDisplayContent.getKeepClearAreas());
makeWindowVisible(w1);
// The returned keep-clear areas contain the areas just from the visible window
- assertEquals(new ArraySet(Arrays.asList(rect1)),
- new ArraySet(mDisplayContent.getKeepClearAreas()));
+ assertEquals(new ArraySet(Arrays.asList(rect1)), mDisplayContent.getKeepClearAreas());
makeWindowVisible(w1, w2);
// The returned keep-clear areas contain the areas from all visible windows
assertEquals(new ArraySet(Arrays.asList(rect1, rect2)),
- new ArraySet(mDisplayContent.getKeepClearAreas()));
+ mDisplayContent.getKeepClearAreas());
}
private void removeRootTaskTests(Runnable runnable) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java b/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
index 66139e6b483a..6a39d5608a19 100644
--- a/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
+++ b/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
@@ -20,6 +20,8 @@ import static org.mockito.Mockito.mock;
import android.view.SurfaceControl;
+import org.mockito.Mockito;
+
/**
* Stubbed {@link SurfaceControl.Builder} class that returns a mocked SurfaceControl instance
* that can be used for unit testing.
@@ -32,6 +34,8 @@ class MockSurfaceControlBuilder extends SurfaceControl.Builder {
@Override
public SurfaceControl build() {
- return mock(SurfaceControl.class);
+ SurfaceControl mockSurfaceControl = mock(SurfaceControl.class);
+ Mockito.doReturn(true).when(mockSurfaceControl).isValid();
+ return mockSurfaceControl;
}
}
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 acceadf8c499..99ba3b806d61 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -949,7 +949,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
LaunchParamsController.LaunchParams launchParams =
new LaunchParamsController.LaunchParams();
launchParams.mPreferredTaskDisplayArea = taskDisplayArea;
- Task root = mRootWindowContainer.getLaunchRootTask(null /* r */, null /* options */,
+ Task root = mRootWindowContainer.getOrCreateRootTask(null /* r */, null /* options */,
null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
0 /* launchParams */);
assertEquals(taskDisplayArea, root.getTaskDisplayArea());
@@ -957,7 +957,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
// Making sure still getting the root task from the preferred TDA when passing in a
// launching activity.
ActivityRecord r = new ActivityBuilder(mAtm).build();
- root = mRootWindowContainer.getLaunchRootTask(r, null /* options */,
+ root = mRootWindowContainer.getOrCreateRootTask(r, null /* options */,
null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
0 /* launchParams */);
assertEquals(taskDisplayArea, root.getTaskDisplayArea());
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 cb858845e03e..33b236669ec7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.server.wm.RunningTasks.FLAG_ALLOWED;
import static com.android.server.wm.RunningTasks.FLAG_CROSS_USERS;
import static com.android.server.wm.RunningTasks.FLAG_KEEP_INTENT_EXTRA;
@@ -81,7 +82,9 @@ public class RunningTasksTest extends WindowTestsBase {
rootTasks.add(task);
}, false /* traverseTopToBottom */);
for (int i = 0; i < numTasks; i++) {
- createTask(rootTasks.get(i % numStacks), ".Task" + i, i, activeTime++, null);
+ final Task task =
+ createTask(rootTasks.get(i % numStacks), ".Task" + i, i, activeTime++, null);
+ doReturn(false).when(task).isVisible();
}
// Ensure that the latest tasks were returned in order of decreasing last active time,
@@ -158,6 +161,36 @@ public class RunningTasksTest extends WindowTestsBase {
}
}
+ @Test
+ public void testUpdateLastActiveTimeOfVisibleTasks() {
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
+ final int numTasks = 10;
+ final ArrayList<Task> tasks = new ArrayList<>();
+ for (int i = 0; i < numTasks; i++) {
+ final Task task = createTask(null, ".Task" + i, i, i, null);
+ doReturn(false).when(task).isVisible();
+ tasks.add(task);
+ }
+
+ final Task visibleTask = tasks.get(0);
+ doReturn(true).when(visibleTask).isVisible();
+
+ final Task focusedTask = tasks.get(1);
+ doReturn(true).when(focusedTask).isVisible();
+ doReturn(true).when(focusedTask).isFocused();
+
+ // Ensure that the last active time of visible tasks were updated while the focused one had
+ // the largest last active time.
+ final int numFetchTasks = 5;
+ final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>();
+ mRunningTasks.getTasks(numFetchTasks, fetchTasks,
+ FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
+ -1 /* callingUid */, PROFILE_IDS);
+ assertThat(fetchTasks).hasSize(numFetchTasks);
+ assertEquals(fetchTasks.get(0).id, focusedTask.mTaskId);
+ assertEquals(fetchTasks.get(1).id, visibleTask.mTaskId);
+ }
+
/**
* Create a task with a single activity in it, with the given last active time.
*/
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index 46ef7ed092de..d27581865e26 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -17,11 +17,13 @@
package com.android.server.wm;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.HardwareBuffer;
import android.os.IBinder;
import android.os.Parcel;
import android.view.InputWindowHandle;
@@ -135,6 +137,12 @@ public class StubTransaction extends SurfaceControl.Transaction {
}
@Override
+ @NonNull
+ public SurfaceControl.Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) {
+ return this;
+ }
+
+ @Override
public SurfaceControl.Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
return this;
}
@@ -275,6 +283,13 @@ public class StubTransaction extends SurfaceControl.Transaction {
}
@Override
+ @NonNull
+ public SurfaceControl.Transaction setBuffer(@NonNull SurfaceControl sc,
+ @Nullable HardwareBuffer buffer) {
+ return this;
+ }
+
+ @Override
public SurfaceControl.Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
return this;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
index 77a8615e20d6..d65b80ae0700 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
@@ -179,11 +179,6 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
mSurfaceHolder.unlockCanvasAndPost(c);
}
- if (mFrameCallback != null) {
- Log.d(TAG, "onFrameComplete");
- mFrameCallback.onFrameComplete();
- }
-
mFrameCallback = null;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index d038fea4680b..f999e4978420 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -101,6 +101,10 @@ public class SystemServicesTestRule implements TestRule {
static int sNextDisplayId = DEFAULT_DISPLAY + 100;
private static final int[] TEST_USER_PROFILE_IDS = {};
+ /** Use a real static object so there won't be NPE in finalize() after clearInlineMocks(). */
+ private static final PowerManager.WakeLock sWakeLock = getInstrumentation().getContext()
+ .getSystemService(PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ private PowerManager.WakeLock mStubbedWakeLock;
private Description mDescription;
private Context mContext;
@@ -194,7 +198,8 @@ public class SystemServicesTestRule implements TestRule {
// Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
final PowerManager pm = mock(PowerManager.class);
doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
- doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString());
+ mStubbedWakeLock = createStubbedWakeLock(false /* needVerification */);
+ doReturn(mStubbedWakeLock).when(pm).newWakeLock(anyInt(), anyString());
// DisplayManagerInternal
final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
@@ -401,6 +406,16 @@ public class SystemServicesTestRule implements TestRule {
return mPowerManagerWrapper;
}
+ /** Creates a no-op wakelock object. */
+ PowerManager.WakeLock createStubbedWakeLock(boolean needVerification) {
+ if (needVerification) {
+ return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+ .spiedInstance(sWakeLock).defaultAnswer(Mockito.RETURNS_DEFAULTS));
+ }
+ return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+ .spiedInstance(sWakeLock).stubOnly());
+ }
+
void setSurfaceFactory(Supplier<Surface> factory) {
mSurfaceFactory = factory;
}
@@ -556,7 +571,7 @@ public class SystemServicesTestRule implements TestRule {
// unit test version does not handle launch wake lock
doNothing().when(this).acquireLaunchWakelock();
- mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
+ mLaunchingActivityWakeLock = mStubbedWakeLock;
initialize();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 8474c3829827..c4547f654c33 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -32,6 +32,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.isIndependent;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -328,6 +329,7 @@ public class TransitionTests extends WindowTestsBase {
final ActivityRecord act = createActivityRecord(tasks[i]);
// alternate so that the transition doesn't get promoted to the display area
act.mVisibleRequested = (i % 2) == 0; // starts invisible
+ act.visibleIgnoringKeyguard = (i % 2) == 0;
if (i == showWallpaperTask) {
doReturn(true).when(act).showWallpaper();
}
@@ -490,6 +492,86 @@ public class TransitionTests extends WindowTestsBase {
}
@Test
+ public void testOpenOpaqueTask() {
+ final Transition transition = createTestTransition(TRANSIT_OPEN);
+ ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ ArraySet<WindowContainer> participants = transition.mParticipants;
+
+ final Task newTask = createTask(mDisplayContent);
+ doReturn(false).when(newTask).isTranslucent(any());
+ final Task oldTask = createTask(mDisplayContent);
+ doReturn(false).when(oldTask).isTranslucent(any());
+
+ final ActivityRecord closing = createActivityRecord(oldTask);
+ closing.setOccludesParent(true);
+ final ActivityRecord opening = createActivityRecord(newTask);
+ opening.setOccludesParent(false);
+ // Start states.
+ changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+ changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+ changes.put(opening, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+ changes.put(closing, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+ fillChangeMap(changes, newTask);
+ // End states.
+ closing.mVisibleRequested = true;
+ opening.mVisibleRequested = true;
+
+ final int transit = transition.mType;
+ int flags = 0;
+
+ // Check basic both tasks participating
+ participants.add(oldTask);
+ participants.add(newTask);
+ ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+ TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+ assertEquals(2, info.getChanges().size());
+ assertEquals(transit, info.getType());
+
+ assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) == 0);
+ assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0);
+ }
+
+ @Test
+ public void testOpenTranslucentTask() {
+ final Transition transition = createTestTransition(TRANSIT_OPEN);
+ ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ ArraySet<WindowContainer> participants = transition.mParticipants;
+
+ final Task newTask = createTask(mDisplayContent);
+ doReturn(true).when(newTask).isTranslucent(any());
+ final Task oldTask = createTask(mDisplayContent);
+ doReturn(false).when(oldTask).isTranslucent(any());
+
+ final ActivityRecord closing = createActivityRecord(oldTask);
+ closing.setOccludesParent(true);
+ final ActivityRecord opening = createActivityRecord(newTask);
+ opening.setOccludesParent(false);
+ // Start states.
+ changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+ changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+ changes.put(opening, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+ changes.put(closing, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+ fillChangeMap(changes, newTask);
+ // End states.
+ closing.mVisibleRequested = true;
+ opening.mVisibleRequested = true;
+
+ final int transit = transition.mType;
+ int flags = 0;
+
+ // Check basic both tasks participating
+ participants.add(oldTask);
+ participants.add(newTask);
+ ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+ TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+ assertEquals(2, info.getChanges().size());
+ assertEquals(transit, info.getType());
+
+ assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) != 0);
+ assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0);
+ }
+
+ @Test
public void testTimeout() {
final TransitionController controller = new TransitionController(mAtm,
mock(TaskSnapshotController.class));
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index a554fab76c2b..e4f691b338e1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -29,6 +29,8 @@ import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -61,6 +63,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
@@ -80,6 +83,7 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.InputConfig;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
@@ -492,6 +496,26 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
+ public void testApplyWithNextDraw() {
+ final WindowState win = createWindow(null, TYPE_APPLICATION_OVERLAY, "app");
+ final SurfaceControl.Transaction[] handledT = { null };
+ // The normal case that the draw transaction is applied with finishing drawing.
+ win.applyWithNextDraw(t -> handledT[0] = t);
+ assertTrue(win.useBLASTSync());
+ final SurfaceControl.Transaction drawT = new StubTransaction();
+ win.prepareDrawHandlers();
+ assertTrue(win.finishDrawing(drawT));
+ assertEquals(drawT, handledT[0]);
+ assertFalse(win.useBLASTSync());
+
+ // If the window is gone before reporting drawn, the sync state should be cleared.
+ win.applyWithNextDraw(t -> handledT[0] = t);
+ win.destroySurfaceUnchecked();
+ assertFalse(win.useBLASTSync());
+ assertNotEquals(drawT, handledT[0]);
+ }
+
+ @Test
public void testSeamlesslyRotateWindow() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
final SurfaceControl.Transaction t = spy(StubTransaction.class);
@@ -733,10 +757,15 @@ public class WindowStateTests extends WindowTestsBase {
assertFalse(win0.canReceiveTouchInput());
}
+ private boolean testFlag(int flags, int test) {
+ return (flags & test) == test;
+ }
+
@Test
public void testUpdateInputWindowHandle() {
final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
win.mAttrs.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+ win.mAttrs.flags = FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH;
final InputWindowHandle handle = new InputWindowHandle(
win.mInputWindowHandle.getInputApplicationHandle(), win.getDisplayId());
final InputWindowHandleWrapper handleWrapper = new InputWindowHandleWrapper(handle);
@@ -746,13 +775,14 @@ public class WindowStateTests extends WindowTestsBase {
mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
assertTrue(handleWrapper.isChanged());
+ assertTrue(testFlag(handle.inputConfig, InputConfig.WATCH_OUTSIDE_TOUCH));
+ assertFalse(testFlag(handle.inputConfig, InputConfig.PREVENT_SPLITTING));
+ assertTrue(testFlag(handle.inputConfig, InputConfig.DISABLE_USER_ACTIVITY));
// The window of standard resizable task should not use surface crop as touchable region.
assertFalse(handle.replaceTouchableRegionWithCrop);
assertEquals(inputChannelToken, handle.token);
assertEquals(win.mActivityRecord.getInputApplicationHandle(false /* update */),
handle.inputApplicationHandle);
- assertEquals(win.mAttrs.inputFeatures, handle.inputFeatures);
- assertEquals(win.isVisible(), handle.visible);
final SurfaceControl sc = mock(SurfaceControl.class);
final SurfaceControl.Transaction transaction = mSystemServicesTestRule.mTransaction;
@@ -778,15 +808,13 @@ public class WindowStateTests extends WindowTestsBase {
assertEquals(rotatedBounds, handle.touchableRegion.getBounds());
// Populate as an overlay to disable the input of window.
- InputMonitor.populateOverlayInputInfo(handleWrapper, false /* isVisible */);
+ InputMonitor.populateOverlayInputInfo(handleWrapper);
// The overlay attributes should be set.
assertTrue(handleWrapper.isChanged());
- assertFalse(handle.focusable);
- assertFalse(handle.visible);
+ assertFalse(handleWrapper.isFocusable());
assertNull(handle.token);
assertEquals(0L, handle.dispatchingTimeoutMillis);
- assertEquals(WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
- handle.inputFeatures);
+ assertTrue(testFlag(handle.inputConfig, InputConfig.NO_INPUT_CHANNEL));
}
@Test
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1999cfc706b4..b290669e103e 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -640,7 +640,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
Slog.e(TAG, "unknown state " + state);
return;
}
- removeMessages(MSG_UPDATE_STATE);
+ if (configured == 0) removeMessages(MSG_UPDATE_STATE);
if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
Message msg = Message.obtain(this, MSG_UPDATE_STATE);
msg.arg1 = connected;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 84bd98347dab..a597fc69a340 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -97,6 +97,7 @@ final class HotwordDetectionConnection {
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;
private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
// TODO: This may need to be a Handler(looper)
@@ -772,7 +773,8 @@ final class HotwordDetectionConnection {
ServiceConnection createLocked() {
ServiceConnection connection =
new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
- IHotwordDetectionService.Stub::asInterface, ++mRestartCount);
+ IHotwordDetectionService.Stub::asInterface,
+ mRestartCount++ % MAX_ISOLATED_PROCESS_NUMBER);
connection.connect();
updateAudioFlinger(connection, mAudioFlinger);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
new file mode 100644
index 000000000000..de0b9606045e
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -0,0 +1,69 @@
+/*
+ * 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.voiceinteraction;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+/**
+ * A utility class for logging hotword statistics event.
+ */
+public final class HotwordMetricsLogger {
+
+ private HotwordMetricsLogger() {
+ // Class only contains static utility functions, and should not be instantiated
+ }
+
+ /**
+ * Logs information related to create hotword detector.
+ */
+ public static void writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid) {
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED, detectorType,
+ isCreated, uid);
+ }
+
+ /**
+ * Logs information related to hotword detection service init result.
+ */
+ public static void writeServiceInitResultEvent(int detectorType, int result) {
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED,
+ detectorType, result);
+ }
+
+ /**
+ * Logs information related to hotword detection service restarting.
+ */
+ public static void writeServiceRestartEvent(int detectorType, int reason) {
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED,
+ detectorType, reason);
+ }
+
+ /**
+ * Logs information related to keyphrase trigger.
+ */
+ public static void writeKeyphraseTriggerEvent(int detectorType, int result) {
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED,
+ detectorType, result);
+ }
+
+ /**
+ * Logs information related to hotword detector events.
+ */
+ public static void writeDetectorEvent(int detectorType, int event, int uid) {
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS,
+ detectorType, event, uid);
+ }
+}
diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp
deleted file mode 100644
index 4fdf34cc1814..000000000000
--- a/startop/iorap/Android.bp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- // 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"],
-}
-
-filegroup {
- name: "services.startop.iorap-javasources",
- srcs: ["src/**/*.java"],
- path: "src",
- visibility: ["//visibility:private"],
-}
-
-filegroup {
- name: "services.startop.iorap-sources",
- srcs: [
- ":services.startop.iorap-javasources",
- ":iorap-aidl",
- ],
- visibility: ["//frameworks/base/services:__subpackages__"],
-}
-
-java_library_static {
- name: "services.startop.iorap",
- srcs: [":services.startop.iorap-sources"],
- libs: ["services.core"],
-}
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING
deleted file mode 100644
index 8c9d4dfb0894..000000000000
--- a/startop/iorap/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presubmit": [
- {
- "name": "libiorap-java-tests"
- }
- ],
- "imports": [
- {
- "path": "system/iorap"
- }
- ]
-}
diff --git a/startop/iorap/functional_tests/Android.bp b/startop/iorap/functional_tests/Android.bp
deleted file mode 100644
index 43c61551cdec..000000000000
--- a/startop/iorap/functional_tests/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
- name: "iorap-functional-tests",
- srcs: ["src/**/*.java"],
- data: [":iorap-functional-test-apps"],
- static_libs: [
- // Non-test dependencies
- // library under test
- "services.startop.iorap",
- // Test Dependencies
- // test android dependencies
- "platform-test-annotations",
- "androidx.test.rules",
- "androidx.test.ext.junit",
- "androidx.test.uiautomator_uiautomator",
- // test framework dependencies
- "truth-prebuilt",
- ],
- dxflags: ["--multi-dex"],
- test_suites: ["device-tests"],
- compile_multilib: "both",
- libs: [
- "android.test.base",
- "android.test.runner",
- ],
- certificate: "platform",
- platform_apis: true,
-}
diff --git a/startop/iorap/functional_tests/AndroidManifest.xml b/startop/iorap/functional_tests/AndroidManifest.xml
deleted file mode 100644
index 6bddc4a39577..000000000000
--- a/startop/iorap/functional_tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.google.android.startop.iorap.tests"
- android:sharedUserId="com.google.android.startop.iorap.tests.functional"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <!--suppress AndroidDomInspection -->
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.google.android.startop.iorap.tests" />
-
- <!--
- 'debuggable=true' is required to properly load mockito jvmti dependencies,
- otherwise it gives the following error at runtime:
-
- Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
- Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
- <application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
- </application>
-</manifest>
diff --git a/startop/iorap/functional_tests/AndroidTest.xml b/startop/iorap/functional_tests/AndroidTest.xml
deleted file mode 100644
index 31d4f6c47b11..000000000000
--- a/startop/iorap/functional_tests/AndroidTest.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<configuration description="Runs iorap-functional-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="test-file-name" value="iorap-functional-tests.apk" />
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
- <target_preparer
- class="com.android.tradefed.targetprep.DeviceSetup">
-
- <!-- iorapd does not pick up the above changes until we restart it -->
- <option name="run-command" value="stop iorapd" />
-
- <!-- Clean up the existing iorap database. -->
- <option name="run-command" value="rm -r /data/misc/iorapd/*" />
- <option name="run-command" value="sleep 1" />
-
- <!-- Set system properties to enable perfetto tracing, readahead and detailed logging. -->
- <option name="run-command" value="setprop iorapd.perfetto.enable true" />
- <option name="run-command" value="setprop iorapd.readahead.enable true" />
- <option name="run-command" value="setprop iorapd.log.verbose true" />
-
- <option name="run-command" value="start iorapd" />
-
- <!-- give it some time to restart the service; otherwise the first unit test might fail -->
- <option name="run-command" value="sleep 1" />
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="abort-on-push-failure" value="true" />
- <option name="push-file"
- key="iorap_test_app_v1.apk"
- value="/data/misc/iorapd/iorap_test_app_v1.apk" />
- <option name="push-file"
- key="iorap_test_app_v2.apk"
- value="/data/misc/iorapd/iorap_test_app_v2.apk" />
- <option name="push-file"
- key="iorap_test_app_v3.apk"
- value="/data/misc/iorapd/iorap_test_app_v3.apk" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.google.android.startop.iorap.tests" />
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- <!-- test-timeout unit is ms, value = 30 min -->
- <option name="test-timeout" value="1800000" />
- </test>
-
-</configuration>
-
diff --git a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
deleted file mode 100644
index 5352be6f283f..000000000000
--- a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
+++ /dev/null
@@ -1,416 +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.google.android.startop.iorapd;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.Until;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.Date;
-import java.util.function.BooleanSupplier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.List;
-import java.text.SimpleDateFormat;
-
-/**
- * Test for the work flow of iorap.
- *
- * <p> This test tests the function of iorap from:
- * perfetto collection -> compilation -> prefetching -> version update -> perfetto collection.
- */
-@RunWith(AndroidJUnit4.class)
-public class IorapWorkFlowTest {
- private static final String TAG = "IorapWorkFlowTest";
-
- private static final String TEST_APP_VERSION_ONE_PATH = "/data/misc/iorapd/iorap_test_app_v1.apk";
- private static final String TEST_APP_VERSION_TWO_PATH = "/data/misc/iorapd/iorap_test_app_v2.apk";
- private static final String TEST_APP_VERSION_THREE_PATH = "/data/misc/iorapd/iorap_test_app_v3.apk";
-
- private static final String DB_PATH = "/data/misc/iorapd/sqlite.db";
- private static final Duration TIMEOUT = Duration.ofSeconds(300L);
-
- private UiDevice mDevice;
-
- @Before
- public void setUp() throws Exception {
- // Initialize UiDevice instance
- mDevice = UiDevice.getInstance(getInstrumentation());
-
- // Start from the home screen
- mDevice.pressHome();
-
- // Wait for launcher
- final String launcherPackage = mDevice.getLauncherPackageName();
- assertThat(launcherPackage, notNullValue());
- mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIMEOUT.getSeconds());
- }
-
- @After
- public void tearDown() throws Exception {
- String packageName = "com.example.ioraptestapp";
- uninstallApk(packageName);
- }
-
- @Test (timeout = 300000)
- public void testNormalWorkFlow() throws Exception {
- assertThat(mDevice, notNullValue());
-
- // Install test app version one
- installApk(TEST_APP_VERSION_ONE_PATH);
- String packageName = "com.example.ioraptestapp";
- String activityName = "com.example.ioraptestapp.MainActivity";
-
- // Perfetto trace collection phase.
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/1L));
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/1L));
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/1L));
-
- // Trigger maintenance service for compilation.
- TimeUnit.SECONDS.sleep(5L);
- assertTrue(compile(packageName, activityName, /*version=*/1L));
-
- // Run app with prefetching
- assertTrue(startAppWithCompiledTrace(
- packageName, activityName, /*version=*/1L));
- }
-
- @Test (timeout = 300000)
- public void testUpdateApp() throws Exception {
- assertThat(mDevice, notNullValue());
-
- // Install test app version two,
- String packageName = "com.example.ioraptestapp";
- String activityName = "com.example.ioraptestapp.MainActivity";
- installApk(TEST_APP_VERSION_TWO_PATH);
-
- // Perfetto trace collection phase.
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/2L));
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/2L));
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/2L));
-
- // Trigger maintenance service for compilation.
- TimeUnit.SECONDS.sleep(5L);
- assertTrue(compile(packageName, activityName, /*version=*/2L));
-
- // Run app with prefetching
- assertTrue(startAppWithCompiledTrace(
- packageName, activityName, /*version=*/2L));
-
- // Update test app to version 3
- installApk(TEST_APP_VERSION_THREE_PATH);
-
- // Rerun app, should do pefetto tracing.
- assertTrue(startAppForPerfettoTrace(
- packageName, activityName, /*version=*/3L));
- }
-
- private static void installApk(String apkPath) throws Exception {
- // Disable the selinux to allow pm install apk in the dir.
- executeShellCommand("setenforce 0");
- executeShellCommand("pm install -r -d " + apkPath);
- executeShellCommand("setenforce 1");
-
- }
-
- private static void uninstallApk(String apkPath) throws Exception {
- executeShellCommand("pm uninstall " + apkPath);
- }
-
- /**
- * Starts the testing app to collect the perfetto trace.
- *
- * @param expectPerfettoTraceCount is the expected count of perfetto traces.
- */
- private boolean startAppForPerfettoTrace(
- String packageName, String activityName, long version)
- throws Exception {
- LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
- return waitForPerfettoTraceSavedFromLogcat(
- packageName, activityName, version, timestamp);
- }
-
- private boolean startAppWithCompiledTrace(
- String packageName, String activityName, long version)
- throws Exception {
- LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
- return waitForPrefetchingFromLogcat(
- packageName, activityName, version, timestamp);
- }
-
- private LogcatTimestamp runAppOnce(String packageName, String activityName) throws Exception {
- // Close the specified app if it's open
- closeApp(packageName);
- LogcatTimestamp timestamp = new LogcatTimestamp();
- // Launch the specified app
- startApp(packageName, activityName);
- // Wait for the app to appear
- mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), TIMEOUT.getSeconds());
- return timestamp;
- }
-
- // Invokes the maintenance to compile the perfetto traces to compiled trace.
- private boolean compile(
- String packageName, String activityName, long version) throws Exception {
- // The job id (283673059) is defined in class IorapForwardingService.
- executeShellCommandViaTmpFile("cmd jobscheduler run -f android 283673059");
- return waitForFileExistence(getCompiledTracePath(packageName, activityName, version));
- }
-
- private String getCompiledTracePath(
- String packageName, String activityName, long version) {
- return String.format(
- "/data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
- packageName, version, activityName);
- }
-
- /**
- * Starts the testing app.
- */
- private void startApp(String packageName, String activityName) throws Exception {
- executeShellCommandViaTmpFile(
- String.format("am start %s/%s", packageName, activityName));
- }
-
- /**
- * Closes the testing app.
- * <p> Keep trying to kill the process of the app until no process of the app package
- * appears.</p>
- */
- private void closeApp(String packageName) throws Exception {
- while (true) {
- String pid = executeShellCommand("pidof " + packageName);
- if (pid.isEmpty()) {
- Log.i(TAG, "Closed app " + packageName);
- return;
- }
- executeShellCommand("kill -9 " + pid);
- TimeUnit.SECONDS.sleep(1L);
- }
- }
-
- /** Waits for a file to appear. */
- private boolean waitForFileExistence(String fileName) throws Exception {
- return retryWithTimeout(TIMEOUT, () -> {
- try {
- String fileExists = executeShellCommandViaTmpFile(
- String.format("test -f %s; echo $?", fileName));
- Log.i(TAG, fileName + " existence is " + fileExists);
- return fileExists.trim().equals("0");
- } catch (Exception e) {
- Log.i(TAG, e.getMessage());
- return false;
- }
- });
- }
-
- /** Waits for the perfetto trace saved message from logcat. */
- private boolean waitForPerfettoTraceSavedFromLogcat(
- String packageName, String activityName, long version, LogcatTimestamp timestamp)
- throws Exception {
- Pattern p = Pattern.compile(".*"
- + getPerfettoTraceSavedIndicator(packageName, activityName, version)
- + "(.*[.]perfetto_trace[.]pb)\n.*", Pattern.DOTALL);
-
- return retryWithTimeout(TIMEOUT, () -> {
- try {
- String log = timestamp.getLogcatAfter();
- Matcher m = p.matcher(log);
- Log.d(TAG, "Tries to find perfetto trace...");
- if (!m.matches()) {
- Log.i(TAG, "Cannot find perfetto trace saved in log.");
- return false;
- }
- String filePath = m.group(1);
- Log.i(TAG, "Perfetto trace is saved to " + filePath);
- return true;
- } catch(Exception e) {
- Log.e(TAG, e.getMessage());
- return false;
- }
- });
- }
-
- private String getPerfettoTraceSavedIndicator(
- String packageName, String activityName, long version) {
- return String.format(
- "Perfetto TraceBuffer saved to file: /data/misc/iorapd/%s/%d/%s/raw_traces/",
- packageName, version, activityName);
- }
-
- /**
- * Waits for the prefetching log in the logcat.
- *
- * <p> When prefetching works, the perfetto traces should not be collected. </p>
- */
- private boolean waitForPrefetchingFromLogcat(
- String packageName, String activityName, long version, LogcatTimestamp timestamp)
- throws Exception {
- Pattern p = Pattern.compile(
- ".*" + getReadaheadIndicator(packageName, activityName, version) +
- ".*Total File Paths=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
- + ".*Total Entries=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
- + ".*Total Bytes=(\\d+) \\(good: (\\d+[.]?\\d*)%\\).*",
- Pattern.DOTALL);
-
- return retryWithTimeout(TIMEOUT, () -> {
- try {
- String log = timestamp.getLogcatAfter();
- Matcher m = p.matcher(log);
- if (!m.matches()) {
- Log.i(TAG, "Cannot find readahead log.");
- return false;
- }
-
- int totalFilePath = Integer.parseInt(m.group(1));
- float totalFilePathGoodRate = Float.parseFloat(m.group(2)) / 100;
- int totalEntries = Integer.parseInt(m.group(3));
- float totalEntriesGoodRate = Float.parseFloat(m.group(4)) / 100;
- int totalBytes = Integer.parseInt(m.group(5));
- float totalBytesGoodRate = Float.parseFloat(m.group(6)) / 100;
-
- Log.i(TAG, String.format(
- "totalFilePath: %d (good %.2f) totalEntries: %d (good %.2f) totalBytes: %d (good %.2f)",
- totalFilePath, totalFilePathGoodRate, totalEntries, totalEntriesGoodRate, totalBytes,
- totalBytesGoodRate));
-
- return totalFilePath > 0 &&
- totalEntries > 0 &&
- totalBytes > 0 &&
- totalFilePathGoodRate > 0.5 &&
- totalEntriesGoodRate > 0.5 &&
- totalBytesGoodRate > 0.5;
- } catch(Exception e) {
- return false;
- }
- });
- }
-
- private static String getReadaheadIndicator(
- String packageName, String activityName, long version) {
- return String.format(
- "Description = /data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
- packageName, version, activityName);
- }
-
- /** Retry until timeout. */
- private boolean retryWithTimeout(Duration timeout, BooleanSupplier supplier) throws Exception {
- long totalSleepTimeSeconds = 0L;
- long sleepIntervalSeconds = 2L;
- while (true) {
- if (supplier.getAsBoolean()) {
- return true;
- }
- TimeUnit.SECONDS.sleep(sleepIntervalSeconds);
- totalSleepTimeSeconds += sleepIntervalSeconds;
- if (totalSleepTimeSeconds > timeout.getSeconds()) {
- return false;
- }
- }
- }
-
- /**
- * Executes command in adb shell via a tmp file.
- *
- * <p> This should be run as root.</p>
- */
- private static String executeShellCommandViaTmpFile(String cmd) throws Exception {
- Log.i(TAG, "Execute via tmp file: " + cmd);
- Path tmp = null;
- try {
- tmp = Files.createTempFile(/*prefix=*/null, /*suffix=*/".sh");
- Files.write(tmp, cmd.getBytes(StandardCharsets.UTF_8));
- tmp.toFile().setExecutable(true);
- return UiDevice.getInstance(
- InstrumentationRegistry.getInstrumentation()).
- executeShellCommand(tmp.toString());
- } finally {
- if (tmp != null) {
- Files.delete(tmp);
- }
- }
- }
-
- /**
- * Executes command in adb shell.
- *
- * <p> This should be run as root.</p>
- */
- private static String executeShellCommand(String cmd) throws Exception {
- Log.i(TAG, "Execute: " + cmd);
- return UiDevice.getInstance(
- InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
- }
-
- static class LogcatTimestamp {
- private String epochTime;
-
- public LogcatTimestamp() throws Exception{
- long currentTimeMillis = System.currentTimeMillis();
- epochTime = String.format(
- "%d.%03d", currentTimeMillis/1000, currentTimeMillis%1000);
- Log.i(TAG, "Current logcat timestamp is " + epochTime);
- }
-
- // For example, 1585264100.000
- public String getEpochTime() {
- return epochTime;
- }
-
- // Gets the logcat after this epoch time.
- public String getLogcatAfter() throws Exception {
- return executeShellCommandViaTmpFile(
- "logcat -v epoch -t '" + epochTime + "'");
- }
- }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
deleted file mode 100644
index 1d38f4c1e23d..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an activity has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onActivityHintEvent<br /><br />
- *
- * Once an activity hint is in {@link #TYPE_STARTED} it must transition to another type.
- * All other states could be terminal, see below: <br /><br />
- *
- * <pre>
- *
- * ┌──────────────────────────────────────┐
- * │ ▼
- * ┌─────────┐ ╔════════════════╗ ╔═══════════╗
- * ──▶ │ STARTED │ ──▶ ║ COMPLETED ║ ──▶ ║ CANCELLED ║
- * └─────────┘ ╚════════════════╝ ╚═══════════╝
- * │
- * │
- * ▼
- * ╔════════════════╗
- * ║ POST_COMPLETED ║
- * ╚════════════════╝
- *
- * </pre> <!-- system/iorap/docs/binder/ActivityHint.dot -->
- *
- * @hide
- */
-public class ActivityHintEvent implements Parcelable {
-
- public static final int TYPE_STARTED = 0;
- public static final int TYPE_CANCELLED = 1;
- public static final int TYPE_COMPLETED = 2;
- public static final int TYPE_POST_COMPLETED = 3;
- private static final int TYPE_MAX = TYPE_POST_COMPLETED;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_STARTED,
- TYPE_CANCELLED,
- TYPE_COMPLETED,
- TYPE_POST_COMPLETED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
- public final ActivityInfo activityInfo;
-
- public ActivityHintEvent(@Type int type, ActivityInfo activityInfo) {
- this.type = type;
- this.activityInfo = activityInfo;
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- Objects.requireNonNull(activityInfo, "activityInfo");
- }
-
- @Override
- public String toString() {
- return String.format("{type: %d, activityInfo: %s}", type, activityInfo);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof ActivityHintEvent) {
- return equals((ActivityHintEvent) other);
- }
- return false;
- }
-
- private boolean equals(ActivityHintEvent other) {
- return type == other.type &&
- Objects.equals(activityInfo, other.activityInfo);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- activityInfo.writeToParcel(out, flags);
- }
-
- private ActivityHintEvent(Parcel in) {
- this.type = in.readInt();
- this.activityInfo = ActivityInfo.CREATOR.createFromParcel(in);
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<ActivityHintEvent> CREATOR
- = new Parcelable.Creator<ActivityHintEvent>() {
- public ActivityHintEvent createFromParcel(Parcel in) {
- return new ActivityHintEvent(in);
- }
-
- public ActivityHintEvent[] newArray(int size) {
- return new ActivityHintEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
deleted file mode 100644
index f47a42cffdd8..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import java.util.Objects;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * Provide minimal information for launched activities to iorap.<br /><br />
- *
- * This uniquely identifies a system-wide activity by providing the {@link #packageName} and
- * {@link #activityName}.
- *
- * @see ActivityHintEvent
- * @see AppIntentEvent
- *
- * @hide
- */
-public class ActivityInfo implements Parcelable {
-
- /** The name of the package, for example {@code com.android.calculator}. */
- public final String packageName;
- /** The name of the activity, for example {@code .activities.activity.MainActivity} */
- public final String activityName;
-
- public ActivityInfo(String packageName, String activityName) {
- this.packageName = packageName;
- this.activityName = activityName;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- Objects.requireNonNull(packageName, "packageName");
- Objects.requireNonNull(activityName, "activityName");
- }
-
- @Override
- public String toString() {
- return String.format("{packageName: %s, activityName: %s}", packageName, activityName);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof ActivityInfo) {
- return equals((ActivityInfo) other);
- }
- return false;
- }
-
- private boolean equals(ActivityInfo other) {
- return Objects.equals(packageName, other.packageName) &&
- Objects.equals(activityName, other.activityName);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(packageName);
- out.writeString(activityName);
- }
-
- private ActivityInfo(Parcel in) {
- packageName = in.readString();
- activityName = in.readString();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<ActivityInfo> CREATOR
- = new Parcelable.Creator<ActivityInfo>() {
- public ActivityInfo createFromParcel(Parcel in) {
- return new ActivityInfo(in);
- }
-
- public ActivityInfo[] newArray(int size) {
- return new ActivityInfo[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
deleted file mode 100644
index 1cd37b5546b9..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a system-wide intent defaults change.<br /><br />
- *
- * Intent defaults provide a mechanism for an app to register itself as an automatic handler.
- * For example the camera app might be registered as the default handler for
- * {@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA} intent. Subsequently,
- * if an arbitrary other app requests for a still image camera photo to be taken, the system
- * will launch the respective default camera app to be launched to handle that request.<br /><br />
- *
- * In some cases iorapd might need to know default intents, e.g. for boot-time pinning of
- * applications that resolve from the default intent. If the application would now be resolved
- * differently, iorapd would unpin the old application and pin the new application.<br /><br />
- *
- * @hide
- */
-public class AppIntentEvent implements Parcelable {
-
- /** @see android.content.Intent#CATEGORY_DEFAULT */
- public static final int TYPE_DEFAULT_INTENT_CHANGED = 0;
- private static final int TYPE_MAX = 0;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_DEFAULT_INTENT_CHANGED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
-
- public final ActivityInfo oldActivityInfo;
- public final ActivityInfo newActivityInfo;
-
- // TODO: Probably need the corresponding action here as well.
-
- public static AppIntentEvent createDefaultIntentChanged(ActivityInfo oldActivityInfo,
- ActivityInfo newActivityInfo) {
- return new AppIntentEvent(TYPE_DEFAULT_INTENT_CHANGED, oldActivityInfo,
- newActivityInfo);
- }
-
- private AppIntentEvent(@Type int type, ActivityInfo oldActivityInfo,
- ActivityInfo newActivityInfo) {
- this.type = type;
- this.oldActivityInfo = oldActivityInfo;
- this.newActivityInfo = newActivityInfo;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- Objects.requireNonNull(oldActivityInfo, "oldActivityInfo");
- Objects.requireNonNull(oldActivityInfo, "newActivityInfo");
- }
-
- @Override
- public String toString() {
- return String.format("{oldActivityInfo: %s, newActivityInfo: %s}", oldActivityInfo,
- newActivityInfo);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof AppIntentEvent) {
- return equals((AppIntentEvent) other);
- }
- return false;
- }
-
- private boolean equals(AppIntentEvent other) {
- return type == other.type &&
- Objects.equals(oldActivityInfo, other.oldActivityInfo) &&
- Objects.equals(newActivityInfo, other.newActivityInfo);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- oldActivityInfo.writeToParcel(out, flags);
- newActivityInfo.writeToParcel(out, flags);
- }
-
- private AppIntentEvent(Parcel in) {
- this.type = in.readInt();
- this.oldActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
- this.newActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<AppIntentEvent> CREATOR
- = new Parcelable.Creator<AppIntentEvent>() {
- public AppIntentEvent createFromParcel(Parcel in) {
- return new AppIntentEvent(in);
- }
-
- public AppIntentEvent[] newArray(int size) {
- return new AppIntentEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
deleted file mode 100644
index 8263e0af4422..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
-import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an app launch sequence has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onAppLaunchEvent <br /><br />
- * @see com.android.server.wm.ActivityMetricsLaunchObserver
- * ActivityMetricsLaunchObserver for the possible event states.
- * @hide
- */
-public abstract class AppLaunchEvent implements Parcelable {
- @LongDef
- @Retention(RetentionPolicy.SOURCE)
- public @interface SequenceId {}
-
- public final @SequenceId
- long sequenceId;
-
- protected AppLaunchEvent(@SequenceId long sequenceId) {
- this.sequenceId = sequenceId;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof AppLaunchEvent) {
- return equals((AppLaunchEvent) other);
- }
- return false;
- }
-
- protected boolean equals(AppLaunchEvent other) {
- return sequenceId == other.sequenceId;
- }
-
-
- @Override
- public String toString() {
- return getClass().getSimpleName() +
- "{" + "sequenceId=" + Long.toString(sequenceId) +
- toStringBody() + "}";
- }
-
- protected String toStringBody() { return ""; };
-
- // List of possible variants:
-
- public static final class IntentStarted extends AppLaunchEvent {
- @NonNull
- public final Intent intent;
- public final long timestampNs;
-
- public IntentStarted(@SequenceId long sequenceId,
- Intent intent,
- long timestampNs) {
- super(sequenceId);
- this.intent = intent;
- this.timestampNs = timestampNs;
-
- Objects.requireNonNull(intent, "intent");
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof IntentStarted) {
- return intent.equals(((IntentStarted)other).intent) &&
- timestampNs == ((IntentStarted)other).timestampNs &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return ", intent=" + intent.toString() +
- " , timestampNs=" + Long.toString(timestampNs);
- }
-
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- IntentProtoParcelable.write(p, intent, flags);
- p.writeLong(timestampNs);
- }
-
- IntentStarted(Parcel p) {
- super(p);
- intent = IntentProtoParcelable.create(p);
- timestampNs = p.readLong();
- }
- }
-
- public static final class IntentFailed extends AppLaunchEvent {
- public IntentFailed(@SequenceId long sequenceId) {
- super(sequenceId);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof IntentFailed) {
- return super.equals(other);
- }
- return false;
- }
-
- IntentFailed(Parcel p) {
- super(p);
- }
- }
-
- public static abstract class BaseWithActivityRecordData extends AppLaunchEvent {
- public final @NonNull
- @ActivityRecordProto byte[] activityRecordSnapshot;
-
- protected BaseWithActivityRecordData(@SequenceId long sequenceId,
- @NonNull @ActivityRecordProto byte[] snapshot) {
- super(sequenceId);
- activityRecordSnapshot = snapshot;
-
- Objects.requireNonNull(snapshot, "snapshot");
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof BaseWithActivityRecordData) {
- return (Arrays.equals(activityRecordSnapshot,
- ((BaseWithActivityRecordData)other).activityRecordSnapshot)) &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return ", " + new String(activityRecordSnapshot);
- }
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
- }
-
- BaseWithActivityRecordData(Parcel p) {
- super(p);
- activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
- }
- }
-
- public static final class ActivityLaunched extends BaseWithActivityRecordData {
- public final @ActivityMetricsLaunchObserver.Temperature
- int temperature;
-
- public ActivityLaunched(@SequenceId long sequenceId,
- @NonNull @ActivityRecordProto byte[] snapshot,
- @ActivityMetricsLaunchObserver.Temperature int temperature) {
- super(sequenceId, snapshot);
- this.temperature = temperature;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ActivityLaunched) {
- return temperature == ((ActivityLaunched)other).temperature &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return super.toStringBody() + ", temperature=" + Integer.toString(temperature);
- }
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- p.writeInt(temperature);
- }
-
- ActivityLaunched(Parcel p) {
- super(p);
- temperature = p.readInt();
- }
- }
-
- public static final class ActivityLaunchFinished extends BaseWithActivityRecordData {
- public final long timestampNs;
-
- public ActivityLaunchFinished(@SequenceId long sequenceId,
- @NonNull @ActivityRecordProto byte[] snapshot,
- long timestampNs) {
- super(sequenceId, snapshot);
- this.timestampNs = timestampNs;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ActivityLaunchFinished) {
- return timestampNs == ((ActivityLaunchFinished)other).timestampNs &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
- }
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- p.writeLong(timestampNs);
- }
-
- ActivityLaunchFinished(Parcel p) {
- super(p);
- timestampNs = p.readLong();
- }
- }
-
- public static class ActivityLaunchCancelled extends AppLaunchEvent {
- public final @Nullable @ActivityRecordProto byte[] activityRecordSnapshot;
-
- public ActivityLaunchCancelled(@SequenceId long sequenceId,
- @Nullable @ActivityRecordProto byte[] snapshot) {
- super(sequenceId);
- activityRecordSnapshot = snapshot;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ActivityLaunchCancelled) {
- return Arrays.equals(activityRecordSnapshot,
- ((ActivityLaunchCancelled)other).activityRecordSnapshot) &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return super.toStringBody() + ", " + new String(activityRecordSnapshot);
- }
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- if (activityRecordSnapshot != null) {
- p.writeBoolean(true);
- ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
- } else {
- p.writeBoolean(false);
- }
- }
-
- ActivityLaunchCancelled(Parcel p) {
- super(p);
- if (p.readBoolean()) {
- activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
- } else {
- activityRecordSnapshot = null;
- }
- }
- }
-
- public static final class ReportFullyDrawn extends BaseWithActivityRecordData {
- public final long timestampNs;
-
- public ReportFullyDrawn(@SequenceId long sequenceId,
- @NonNull @ActivityRecordProto byte[] snapshot,
- long timestampNs) {
- super(sequenceId, snapshot);
- this.timestampNs = timestampNs;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ReportFullyDrawn) {
- return timestampNs == ((ReportFullyDrawn)other).timestampNs &&
- super.equals(other);
- }
- return false;
- }
-
- @Override
- protected String toStringBody() {
- return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
- }
-
- @Override
- protected void writeToParcelImpl(Parcel p, int flags) {
- super.writeToParcelImpl(p, flags);
- p.writeLong(timestampNs);
- }
-
- ReportFullyDrawn(Parcel p) {
- super(p);
- timestampNs = p.readLong();
- }
- }
-
- @Override
- public @ContentsFlags int describeContents() { return 0; }
-
- @Override
- public void writeToParcel(Parcel p, @WriteFlags int flags) {
- p.writeInt(getTypeIndex());
-
- writeToParcelImpl(p, flags);
- }
-
-
- public static Creator<AppLaunchEvent> CREATOR =
- new Creator<AppLaunchEvent>() {
- @Override
- public AppLaunchEvent createFromParcel(Parcel source) {
- int typeIndex = source.readInt();
-
- Class<?> kls = getClassFromTypeIndex(typeIndex);
- if (kls == null) {
- throw new IllegalArgumentException("Invalid type index: " + typeIndex);
- }
-
- try {
- return (AppLaunchEvent) kls.getConstructor(Parcel.class).newInstance(source);
- } catch (InstantiationException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- }
- }
-
- @Override
- public AppLaunchEvent[] newArray(int size) {
- return new AppLaunchEvent[0];
- }
- };
-
- protected void writeToParcelImpl(Parcel p, int flags) {
- p.writeLong(sequenceId);
- }
-
- protected AppLaunchEvent(Parcel p) {
- sequenceId = p.readLong();
- }
-
- private int getTypeIndex() {
- for (int i = 0; i < sTypes.length; ++i) {
- if (sTypes[i].equals(this.getClass())) {
- return i;
- }
- }
- throw new AssertionError("sTypes did not include this type: " + this.getClass());
- }
-
- private static @Nullable Class<?> getClassFromTypeIndex(int typeIndex) {
- if (typeIndex >= 0 && typeIndex < sTypes.length) {
- return sTypes[typeIndex];
- }
- return null;
- }
-
- // Index position matters: It is used to encode the specific type in parceling.
- // Keep up-to-date with C++ side.
- private static Class<?>[] sTypes = new Class[] {
- IntentStarted.class,
- IntentFailed.class,
- ActivityLaunched.class,
- ActivityLaunchFinished.class,
- ActivityLaunchCancelled.class,
- ReportFullyDrawn.class,
- };
-
- public static class ActivityRecordProtoParcelable {
- public static void write(Parcel p, @ActivityRecordProto byte[] activityRecordSnapshot,
- int flags) {
- p.writeByteArray(activityRecordSnapshot);
- }
-
- public static @ActivityRecordProto byte[] create(Parcel p) {
- byte[] data = p.createByteArray();
-
- return data;
- }
- }
-
- public static class IntentProtoParcelable {
- private static final int INTENT_PROTO_CHUNK_SIZE = 1024;
-
- public static void write(Parcel p, @NonNull Intent intent, int flags) {
- // There does not appear to be a way to 'reset' a ProtoOutputBuffer stream,
- // so create a new one every time.
- final ProtoOutputStream protoOutputStream =
- new ProtoOutputStream(INTENT_PROTO_CHUNK_SIZE);
- // Write this data out as the top-most IntentProto (i.e. it is not a sub-object).
- intent.dumpDebug(protoOutputStream);
- final byte[] bytes = protoOutputStream.getBytes();
-
- p.writeByteArray(bytes);
- }
-
- // TODO: Should be mockable for testing?
- // We cannot deserialize in the platform because we don't have a 'readFromProto'
- // code.
- public static @NonNull Intent create(Parcel p) {
- // This will "read" the correct amount of data, but then we discard it.
- byte[] data = p.createByteArray();
-
- // Never called by real code in a platform, this binder API is implemented only in C++.
- return new Intent("<cannot deserialize IntentProto>");
- }
- }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
deleted file mode 100644
index 34aedd7685d8..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.startop.iorap;
-
-/**
- * Convenience short-hand to throw {@link IllegalAccessException} when the arguments
- * are out-of-range.
- */
-public class CheckHelpers {
- /** @throws IllegalAccessException if {@param type} is not in {@code [0..maxValue]} */
- public static void checkTypeInRange(int type, int maxValue) {
- if (type < 0) {
- throw new IllegalArgumentException(
- String.format("type must be non-negative (value=%d)", type));
- }
- if (type > maxValue) {
- throw new IllegalArgumentException(
- String.format("type out of range (value=%d, max=%d)", type, maxValue));
- }
- }
-
- /** @throws IllegalAccessException if {@param state} is not in {@code [0..maxValue]} */
- public static void checkStateInRange(int state, int maxValue) {
- if (state < 0) {
- throw new IllegalArgumentException(
- String.format("state must be non-negative (value=%d)", state));
- }
- if (state > maxValue) {
- throw new IllegalArgumentException(
- String.format("state out of range (value=%d, max=%d)", state, maxValue));
- }
- }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
deleted file mode 100644
index 72c5eaa84c96..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
+++ /dev/null
@@ -1,114 +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.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a package is updated by dexopt service.<br /><br />
- *
- * @hide
- */
-public class DexOptEvent implements Parcelable {
- public static final int TYPE_PACKAGE_UPDATE = 0;
- private static final int TYPE_MAX = 0;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_PACKAGE_UPDATE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
- public final String packageName;
-
- @NonNull
- public static DexOptEvent createPackageUpdate(String packageName) {
- return new DexOptEvent(TYPE_PACKAGE_UPDATE, packageName);
- }
-
- private DexOptEvent(@Type int type, String packageName) {
- this.type = type;
- this.packageName = packageName;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- Objects.requireNonNull(packageName, "packageName");
- }
-
- @Override
- public String toString() {
- return String.format("{DexOptEvent: packageName: %s}", packageName);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof DexOptEvent) {
- return equals((DexOptEvent) other);
- }
- return false;
- }
-
- private boolean equals(DexOptEvent other) {
- return packageName.equals(other.packageName);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- out.writeString(packageName);
- }
-
- private DexOptEvent(Parcel in) {
- this.type = in.readInt();
- this.packageName = in.readString();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<DexOptEvent> CREATOR
- = new Parcelable.Creator<DexOptEvent>() {
- public DexOptEvent createFromParcel(Parcel in) {
- return new DexOptEvent(in);
- }
-
- public DexOptEvent[] newArray(int size) {
- return new DexOptEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
deleted file mode 100644
index dcaff26b79c6..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
+++ /dev/null
@@ -1,267 +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 com.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.util.Log;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-
-import java.io.StringWriter;
-import java.io.PrintWriter;
-
-/**
- * A validator to check the correctness of event sequence during app startup.
- *
- * <p> A valid state transition of event sequence is shown as the following:
- *
- * <pre>
- *
- * +--------------------+
- * | |
- * | INIT |
- * | |
- * +--------------------+
- * |
- * |
- * ↓
- * +--------------------+
- * | |
- * +-------------------| INTENT_STARTED | ←--------------------------------+
- * | | | |
- * | +--------------------+ |
- * | | |
- * | | |
- * ↓ ↓ |
- * +--------------------+ +--------------------+ |
- * | | | | |
- * | INTENT_FAILED | | ACTIVITY_LAUNCHED |------------------+ |
- * | | | | | |
- * +--------------------+ +--------------------+ | |
- * | | | |
- * | ↓ ↓ |
- * | +--------------------+ +--------------------+ |
- * | | | | | |
- * +------------------ | ACTIVITY_FINISHED | | ACTIVITY_CANCELLED | |
- * | | | | | |
- * | +--------------------+ +--------------------+ |
- * | | | |
- * | | | |
- * | ↓ | |
- * | +--------------------+ | |
- * | | | | |
- * | | REPORT_FULLY_DRAWN | | |
- * | | | | |
- * | +--------------------+ | |
- * | | | |
- * | | | |
- * | ↓ | |
- * | +--------------------+ | |
- * | | | | |
- * +-----------------→ | END |←-----------------+ |
- * | | |
- * +--------------------+ |
- * | |
- * | |
- * | |
- * +---------------------------------------------
- *
- * <p> END is not a real state in implementation. All states that points to END directly
- * could transition to INTENT_STARTED.
- *
- * <p> If any bad transition happened, the state becomse UNKNOWN. The UNKNOWN state
- * could be accumulated, because during the UNKNOWN state more IntentStarted may
- * be triggered. To recover from UNKNOWN to INIT, all the accumualted IntentStarted
- * should termniate.
- *
- * <p> During UNKNOWN state, each IntentStarted increases the accumulation, and any of
- * IntentFailed, ActivityLaunchCancelled and ActivityFinished decreases the accumulation.
- * ReportFullyDrawn doesn't impact the accumulation.
- */
-public class EventSequenceValidator implements ActivityMetricsLaunchObserver {
- static final String TAG = "EventSequenceValidator";
- /** $> adb shell 'setprop log.tag.EventSequenceValidator VERBOSE' */
- public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private State state = State.INIT;
- private long accIntentStartedEvents = 0;
-
- @Override
- public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("IntentStarted during UNKNOWN. " + intent);
- incAccIntentStartedEvents();
- return;
- }
-
- if (state != State.INIT &&
- state != State.INTENT_FAILED &&
- state != State.ACTIVITY_CANCELLED &&
- state != State.ACTIVITY_FINISHED &&
- state != State.REPORT_FULLY_DRAWN) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.INTENT_STARTED));
- incAccIntentStartedEvents();
- incAccIntentStartedEvents();
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED));
- state = State.INTENT_STARTED;
- }
-
- @Override
- public void onIntentFailed() {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("onIntentFailed during UNKNOWN.");
- decAccIntentStartedEvents();
- return;
- }
- if (state != State.INTENT_STARTED) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.INTENT_FAILED));
- incAccIntentStartedEvents();
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED));
- state = State.INTENT_FAILED;
- }
-
- @Override
- public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
- @Temperature int temperature) {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("onActivityLaunched during UNKNOWN.");
- return;
- }
- if (state != State.INTENT_STARTED) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
- incAccIntentStartedEvents();
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
- state = State.ACTIVITY_LAUNCHED;
- }
-
- @Override
- public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("onActivityLaunchCancelled during UNKNOWN.");
- decAccIntentStartedEvents();
- return;
- }
- if (state != State.ACTIVITY_LAUNCHED) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.ACTIVITY_CANCELLED));
- incAccIntentStartedEvents();
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED));
- state = State.ACTIVITY_CANCELLED;
- }
-
- @Override
- public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
- long timestampNs) {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("onActivityLaunchFinished during UNKNOWN.");
- decAccIntentStartedEvents();
- return;
- }
-
- if (state != State.ACTIVITY_LAUNCHED) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.ACTIVITY_FINISHED));
- incAccIntentStartedEvents();
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED));
- state = State.ACTIVITY_FINISHED;
- }
-
- @Override
- public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
- long timestampNs) {
- if (state == State.UNKNOWN) {
- logWarningWithStackTrace("onReportFullyDrawn during UNKNOWN.");
- return;
- }
- if (state == State.INIT) {
- return;
- }
-
- if (state != State.ACTIVITY_FINISHED) {
- logWarningWithStackTrace(
- String.format("Cannot transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
- return;
- }
-
- Log.i(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
- state = State.REPORT_FULLY_DRAWN;
- }
-
- enum State {
- INIT,
- INTENT_STARTED,
- INTENT_FAILED,
- ACTIVITY_LAUNCHED,
- ACTIVITY_CANCELLED,
- ACTIVITY_FINISHED,
- REPORT_FULLY_DRAWN,
- UNKNOWN,
- }
-
- private void incAccIntentStartedEvents() {
- if (accIntentStartedEvents < 0) {
- throw new AssertionError("The number of unknowns cannot be negative");
- }
- if (accIntentStartedEvents == 0) {
- state = State.UNKNOWN;
- }
- ++accIntentStartedEvents;
- Log.i(TAG,
- String.format("inc AccIntentStartedEvents to %d", accIntentStartedEvents));
- }
-
- private void decAccIntentStartedEvents() {
- if (accIntentStartedEvents <= 0) {
- throw new AssertionError("The number of unknowns cannot be negative");
- }
- if(accIntentStartedEvents == 1) {
- state = State.INIT;
- }
- --accIntentStartedEvents;
- Log.i(TAG,
- String.format("dec AccIntentStartedEvents to %d", accIntentStartedEvents));
- }
-
- private void logWarningWithStackTrace(String log) {
- if (DEBUG) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw);
- Log.wtf(TAG, String.format("%s\n%s", log, sw));
- }
- }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
deleted file mode 100644
index 77046f2276e9..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-// TODO: rename to com.android.server.startop.iorap
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.DeviceConfig;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.IoThread;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.pm.BackgroundDexOptService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
-import com.android.server.wm.ActivityTaskManagerInternal;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.BooleanSupplier;
-
-/**
- * System-server-local proxy into the {@code IIorap} native service.
- */
-public class IorapForwardingService extends SystemService {
-
- public static final String TAG = "IorapForwardingService";
- /** $> adb shell 'setprop log.tag.IorapForwardingService VERBOSE' */
- public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- /** $> adb shell 'setprop ro.iorapd.enable true' */
- private static boolean IS_ENABLED = SystemProperties.getBoolean("ro.iorapd.enable", true);
- /** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */
- private static boolean WTF_CRASH = SystemProperties.getBoolean(
- "iorapd.forwarding_service.wtf_crash", false);
- private static final Duration TIMEOUT = Duration.ofSeconds(600L);
-
- // "Unique" job ID from the service name. Also equal to 283673059.
- public static final int JOB_ID_IORAPD = encodeEnglishAlphabetStringIntoInt("iorapd");
- // Run every 24 hours.
- public static final long JOB_INTERVAL_MS = TimeUnit.HOURS.toMillis(24);
-
- private IIorap mIorapRemote;
- private final Object mLock = new Object();
- /** Handle onBinderDeath by periodically trying to reconnect. */
- private final Handler mHandler =
- new BinderConnectionHandler(IoThread.getHandler().getLooper());
-
- private volatile IorapdJobService mJobService; // Write-once (null -> non-null forever).
- private volatile static IorapForwardingService sSelfService; // Write once (null -> non-null).
-
-
- /**
- * Atomics set to true if the JobScheduler requests an abort.
- */
- private final AtomicBoolean mAbortIdleCompilation = new AtomicBoolean(false);
-
- /**
- * Initializes the system service.
- * <p>
- * Subclasses must define a single argument constructor that accepts the context
- * and passes it to super.
- * </p>
- *
- * @param context The system server context.
- */
- public IorapForwardingService(Context context) {
- super(context);
-
- if (DEBUG) {
- Log.v(TAG, "IorapForwardingService (Context=" + context.toString() + ")");
- }
-
- if (sSelfService != null) {
- throw new AssertionError("only one service instance allowed");
- }
- sSelfService = this;
- }
-
- //<editor-fold desc="Providers">
- /*
- * Providers for external dependencies:
- * - These are marked as protected to allow tests to inject different values via mocks.
- */
-
- @VisibleForTesting
- protected ActivityMetricsLaunchObserverRegistry provideLaunchObserverRegistry() {
- ActivityTaskManagerInternal amtInternal =
- LocalServices.getService(ActivityTaskManagerInternal.class);
- ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
- amtInternal.getLaunchObserverRegistry();
- return launchObserverRegistry;
- }
-
- @VisibleForTesting
- protected IIorap provideIorapRemote() {
- IIorap iorap;
- try {
- iorap = IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"));
- } catch (ServiceManager.ServiceNotFoundException e) {
- Log.w(TAG, e.getMessage());
- return null;
- }
-
- try {
- iorap.asBinder().linkToDeath(provideDeathRecipient(), /*flags*/0);
- } catch (RemoteException e) {
- handleRemoteError(e);
- return null;
- }
-
- return iorap;
- }
-
- @VisibleForTesting
- protected DeathRecipient provideDeathRecipient() {
- return new DeathRecipient() {
- @Override
- public void binderDied() {
- Log.w(TAG, "iorapd has died");
- retryConnectToRemoteAndConfigure(/*attempts*/0);
-
- if (mJobService != null) {
- mJobService.onIorapdDisconnected();
- }
- }
- };
- }
-
- @VisibleForTesting
- protected boolean isIorapEnabled() {
- // These two mendel flags should match those in iorapd native process
- // system/iorapd/src/common/property.h
- boolean isTracingEnabled =
- getMendelFlag("iorap_perfetto_enable", "iorapd.perfetto.enable", false);
- boolean isReadAheadEnabled =
- getMendelFlag("iorap_readahead_enable", "iorapd.readahead.enable", false);
- // Same as the property in iorapd.rc -- disabling this will mean the 'iorapd' binder process
- // never comes up, so all binder connections will fail indefinitely.
- return IS_ENABLED && (isTracingEnabled || isReadAheadEnabled);
- }
-
- private boolean getMendelFlag(String mendelFlag, String sysProperty, boolean defaultValue) {
- // TODO(yawanng) use DeviceConfig to get mendel property.
- // DeviceConfig doesn't work and the reason is not clear.
- // Provider service is already up before IORapForwardService.
- String mendelProperty = "persist.device_config."
- + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT
- + "."
- + mendelFlag;
- return SystemProperties.getBoolean(mendelProperty,
- SystemProperties.getBoolean(sysProperty, defaultValue));
- }
-
- //</editor-fold>
-
- @Override
- public void onStart() {
- if (DEBUG) {
- Log.v(TAG, "onStart");
- }
-
- retryConnectToRemoteAndConfigure(/*attempts*/0);
- }
-
- @Override
- public void onBootPhase(int phase) {
- if (phase == PHASE_BOOT_COMPLETED) {
- if (DEBUG) {
- Log.v(TAG, "onBootPhase(PHASE_BOOT_COMPLETED)");
- }
-
- if (isIorapEnabled()) {
- // Set up a recurring background job. This has to be done in a later phase since it
- // has a dependency the job scheduler.
- //
- // Doing this too early can result in a ServiceNotFoundException for 'jobservice'
- // or a null reference for #getSystemService(JobScheduler.class)
- mJobService = new IorapdJobService(getContext());
- }
- }
- }
-
- private class BinderConnectionHandler extends Handler {
- public BinderConnectionHandler(android.os.Looper looper) {
- super(looper);
- }
-
- public static final int MESSAGE_BINDER_CONNECT = 0;
-
- private int mAttempts = 0;
-
- @Override
- public void handleMessage(android.os.Message message) {
- switch (message.what) {
- case MESSAGE_BINDER_CONNECT:
- if (!retryConnectToRemoteAndConfigure(mAttempts)) {
- mAttempts++;
- } else {
- mAttempts = 0;
- }
- break;
- default:
- throw new AssertionError("Unknown message: " + message.toString());
- }
- }
- }
-
- /**
- * Handle iorapd shutdowns and crashes, by attempting to reconnect
- * until the service is reached again.
- *
- * <p>The first connection attempt is synchronous,
- * subsequent attempts are done by posting delayed tasks to the IoThread.</p>
- *
- * @return true if connection succeeded now, or false if it failed now [and needs to requeue].
- */
- private boolean retryConnectToRemoteAndConfigure(int attempts) {
- final int sleepTime = 1000; // ms
-
- if (DEBUG) {
- Log.v(TAG, "retryConnectToRemoteAndConfigure - attempt #" + attempts);
- }
-
- if (connectToRemoteAndConfigure()) {
- return true;
- }
-
- // Either 'iorapd' is stuck in a crash loop (ouch!!) or we manually
- // called 'adb shell stop iorapd' , which means this would loop until it comes back
- // up.
- //
- // TODO: it would be good to get nodified of 'adb shell stop iorapd' to avoid
- // printing this warning.
- if (DEBUG) {
- Log.v(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime);
- }
-
- // Use a handler instead of Thread#sleep to avoid backing up the binder thread
- // when this is called from the death recipient callback.
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(BinderConnectionHandler.MESSAGE_BINDER_CONNECT),
- sleepTime);
-
- return false;
-
- // Log.e(TAG, "Can't connect to iorapd - giving up after " + attempts + " attempts");
- }
-
- private boolean connectToRemoteAndConfigure() {
- synchronized (mLock) {
- // Synchronize against any concurrent calls to this via the DeathRecipient.
- return connectToRemoteAndConfigureLocked();
- }
- }
-
- private boolean connectToRemoteAndConfigureLocked() {
- if (!isIorapEnabled()) {
- if (DEBUG) {
- Log.v(TAG, "connectToRemoteAndConfigure - iorapd is disabled, skip rest of work");
- }
- // When we see that iorapd is disabled (when system server comes up),
- // it stays disabled permanently until the next system server reset.
-
- // TODO: consider listening to property changes as a callback, then we can
- // be more dynamic about handling enable/disable.
- return true;
- }
-
- // Connect to the native binder service.
- mIorapRemote = provideIorapRemote();
- if (mIorapRemote == null) {
- if (DEBUG) {
- Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
- }
- return false;
- }
- invokeRemote(mIorapRemote,
- (IIorap remote) -> remote.setTaskListener(new RemoteTaskListener()) );
- registerInProcessListenersLocked();
-
- Log.i(TAG, "Connected to iorapd native service.");
-
- return true;
- }
-
- private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver();
- private final EventSequenceValidator mEventSequenceValidator = new EventSequenceValidator();
- private final DexOptPackagesUpdated mDexOptPackagesUpdated = new DexOptPackagesUpdated();
- private boolean mRegisteredListeners = false;
-
- private void registerInProcessListenersLocked() {
- if (mRegisteredListeners) {
- // Listeners are registered only once (idempotent operation).
- //
- // Today listeners are tolerant of the remote side going away
- // by handling remote errors.
- //
- // We could try to 'unregister' the listener when we get a binder disconnect,
- // but we'd still have to handle the case of encountering synchronous errors so
- // it really wouldn't be a win (other than having less log spew).
- return;
- }
-
- // Listen to App Launch Sequence events from ActivityTaskManager,
- // and forward them to the native binder service.
- ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
- provideLaunchObserverRegistry();
- launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver);
- launchObserverRegistry.registerLaunchObserver(mEventSequenceValidator);
-
- BackgroundDexOptService.getService().addPackagesUpdatedListener(
- mDexOptPackagesUpdated);
-
-
- mRegisteredListeners = true;
- }
-
- private class DexOptPackagesUpdated implements BackgroundDexOptService.PackagesUpdatedListener {
- @Override
- public void onPackagesUpdated(ArraySet<String> updatedPackages) {
- String[] updated = updatedPackages.toArray(new String[0]);
- for (String packageName : updated) {
- Log.d(TAG, "onPackagesUpdated: " + packageName);
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onDexOptEvent(RequestId.nextValueForSequence(),
- DexOptEvent.createPackageUpdate(packageName))
- );
- }
- }
- }
-
- private class AppLaunchObserver implements ActivityMetricsLaunchObserver {
- // We add a synthetic sequence ID here to make it easier to differentiate new
- // launch sequences on the native side.
- private @AppLaunchEvent.SequenceId long mSequenceId = -1;
-
- // All callbacks occur on the same background thread. Don't synchronize explicitly.
-
- @Override
- public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
- // #onIntentStarted [is the only transition that] initiates a new launch sequence.
- ++mSequenceId;
-
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onIntentStarted(%d, %s, %d)",
- mSequenceId, intent, timestampNs));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.IntentStarted(mSequenceId, intent, timestampNs))
- );
- }
-
- @Override
- public void onIntentFailed() {
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onIntentFailed(%d)", mSequenceId));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.IntentFailed(mSequenceId))
- );
- }
-
- @Override
- public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
- @Temperature int temperature) {
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunched(%d, %s, %d)",
- mSequenceId, activity, temperature));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.ActivityLaunched(mSequenceId, activity, temperature))
- );
- }
-
- @Override
- public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchCancelled(%d, %s)",
- mSequenceId, activity));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.ActivityLaunchCancelled(mSequenceId,
- activity)));
- }
-
- @Override
- public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
- long timestampNs) {
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchFinished(%d, %s, %d)",
- mSequenceId, activity, timestampNs));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.ActivityLaunchFinished(mSequenceId,
- activity,
- timestampNs))
- );
- }
-
- @Override
- public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
- long timestampNs) {
- if (DEBUG) {
- Log.v(TAG, String.format("AppLaunchObserver#onReportFullyDrawn(%d, %s, %d)",
- mSequenceId, activity, timestampNs));
- }
-
- invokeRemote(mIorapRemote,
- (IIorap remote) ->
- remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
- new AppLaunchEvent.ReportFullyDrawn(mSequenceId, activity, timestampNs))
- );
- }
- }
-
- /**
- * Debugging:
- *
- * $> adb shell dumpsys jobscheduler
- *
- * Search for 'IorapdJobServiceProxy'.
- *
- * JOB #1000/283673059: 6e54ed android/com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy
- * ^ ^ ^
- * (uid, job id) ComponentName(package/class)
- *
- * Forcing the job to be run, ignoring constraints:
- *
- * $> adb shell cmd jobscheduler run -f android 283673059
- * ^ ^
- * package job_id
- *
- * ------------------------------------------------------------
- *
- * This class is instantiated newly by the JobService every time
- * it wants to run a new job.
- *
- * We need to forward invocations to the current running instance of
- * IorapForwardingService#IorapdJobService.
- *
- * Visibility: Must be accessible from android.app.AppComponentFactory
- */
- public static class IorapdJobServiceProxy extends JobService {
-
- public IorapdJobServiceProxy() {
- getActualIorapdJobService().bindProxy(this);
- }
-
-
- @NonNull
- private IorapdJobService getActualIorapdJobService() {
- // Can't ever be null, because the guarantee is that the
- // IorapForwardingService is always running.
- // We are in the same process as Job Service.
- return sSelfService.mJobService;
- }
-
- // Called by system to start the job.
- @Override
- public boolean onStartJob(JobParameters params) {
- return getActualIorapdJobService().onStartJob(params);
- }
-
- // Called by system to prematurely stop the job.
- @Override
- public boolean onStopJob(JobParameters params) {
- return getActualIorapdJobService().onStopJob(params);
- }
- }
-
- private class IorapdJobService extends JobService {
- private final ComponentName IORAPD_COMPONENT_NAME;
-
- private final Object mLock = new Object();
- // Jobs currently running remotely on iorapd.
- // They were started by the JobScheduler and need to be finished.
- private final HashMap<RequestId, JobParameters> mRunningJobs = new HashMap<>();
-
- private final JobInfo IORAPD_JOB_INFO;
-
- private volatile IorapdJobServiceProxy mProxy;
-
- public void bindProxy(IorapdJobServiceProxy proxy) {
- mProxy = proxy;
- }
-
- // Create a new job service which immediately schedules a 24-hour idle maintenance mode
- // background job to execute.
- public IorapdJobService(Context context) {
- if (DEBUG) {
- Log.v(TAG, "IorapdJobService (Context=" + context.toString() + ")");
- }
-
- // Schedule the proxy class to be instantiated by the JobScheduler
- // when it is time to invoke background jobs for IorapForwardingService.
-
-
- // This also needs a BIND_JOB_SERVICE permission in
- // frameworks/base/core/res/AndroidManifest.xml
- IORAPD_COMPONENT_NAME = new ComponentName(context, IorapdJobServiceProxy.class);
-
- JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_IORAPD, IORAPD_COMPONENT_NAME);
- builder.setPeriodic(JOB_INTERVAL_MS);
-
- builder.setRequiresCharging(true);
- builder.setRequiresDeviceIdle(true);
-
- builder.setRequiresStorageNotLow(true);
-
- IORAPD_JOB_INFO = builder.build();
-
- JobScheduler js = context.getSystemService(JobScheduler.class);
- js.schedule(IORAPD_JOB_INFO);
- Log.d(TAG,
- "BgJob Scheduled (jobId=" + JOB_ID_IORAPD
- + ", interval: " + JOB_INTERVAL_MS + "ms)");
- }
-
- // Called by system to start the job.
- @Override
- public boolean onStartJob(JobParameters params) {
- // Tell iorapd to start a background job.
- Log.d(TAG, "Starting background job: " + params.toString());
-
- mAbortIdleCompilation.set(false);
- // PackageManagerService starts before IORap service.
- PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
- List<String> pkgs = pm.getAllPackages();
- runIdleCompilationAsync(params, pkgs);
- return true;
- }
-
- private void runIdleCompilationAsync(final JobParameters params, final List<String> pkgs) {
- new Thread("IORap_IdleCompilation") {
- @Override
- public void run() {
- for (int i = 0; i < pkgs.size(); i++) {
- String pkg = pkgs.get(i);
- if (mAbortIdleCompilation.get()) {
- Log.i(TAG, "The idle compilation is aborted");
- return;
- }
-
- // We wait until that job's sequence ID returns to us with 'Completed',
- RequestId request;
- synchronized (mLock) {
- // TODO: would be cleaner if we got the request from the
- // 'invokeRemote' function. Better yet, consider
- // a Pair<RequestId, Future<TaskResult>> or similar.
- request = RequestId.nextValueForSequence();
- mRunningJobs.put(request, params);
- }
-
- Log.i(TAG, String.format("IORap compile package: %s, [%d/%d]",
- pkg, i + 1, pkgs.size()));
- boolean shouldUpdateVersions = (i == 0);
- if (!invokeRemote(mIorapRemote, (IIorap remote) ->
- remote.onJobScheduledEvent(request,
- JobScheduledEvent.createIdleMaintenance(
- JobScheduledEvent.TYPE_START_JOB,
- params,
- pkg,
- shouldUpdateVersions)))) {
- synchronized (mLock) {
- mRunningJobs.remove(request); // Avoid memory leaks.
- }
- }
-
- // Wait until the job is complete and removed from the running jobs.
- retryWithTimeout(TIMEOUT, () -> {
- synchronized (mLock) {
- return !mRunningJobs.containsKey(request);
- }
- });
- }
-
- // Finish the job after all packages are compiled.
- if (mProxy != null) {
- mProxy.jobFinished(params, /*reschedule*/false);
- }
- }
- }.start();
- }
-
- /** Retry until timeout. */
- private boolean retryWithTimeout(final Duration timeout, BooleanSupplier supplier) {
- long totalSleepTimeMs = 0L;
- long sleepIntervalMs = 10L;
- while (true) {
- if (supplier.getAsBoolean()) {
- return true;
- }
- try {
- TimeUnit.MILLISECONDS.sleep(sleepIntervalMs);
- } catch (InterruptedException e) {
- Log.e(TAG, e.getMessage());
- return false;
- }
-
- totalSleepTimeMs += sleepIntervalMs;
- if (totalSleepTimeMs > timeout.toMillis()) {
- return false;
- }
- }
- }
-
- // Called by system to prematurely stop the job.
- @Override
- public boolean onStopJob(JobParameters params) {
- // As this is unexpected behavior, print a warning.
- Log.w(TAG, "onStopJob(params=" + params.toString() + ")");
- mAbortIdleCompilation.set(true);
-
- // Yes, retry the job at a later time no matter what.
- return true;
- }
-
- // Listen to *all* task completes for all requests.
- // The majority of these might be unrelated to background jobs.
- public void onIorapdTaskCompleted(RequestId requestId) {
- JobParameters jobParameters;
- synchronized (mLock) {
- jobParameters = mRunningJobs.remove(requestId);
- }
-
- // Typical case: This was a task callback unrelated to our jobs.
- if (jobParameters == null) {
- return;
- }
-
- if (DEBUG) {
- Log.v(TAG,
- String.format("IorapdJobService#onIorapdTaskCompleted(%s), found params=%s",
- requestId, jobParameters));
- }
-
- Log.d(TAG, "Finished background job: " + jobParameters.toString());
- }
-
- public void onIorapdDisconnected() {
- synchronized (mLock) {
- mRunningJobs.clear();
- }
-
- if (DEBUG) {
- Log.v(TAG, String.format("IorapdJobService#onIorapdDisconnected"));
- }
-
- // TODO: should we try to resubmit all incomplete jobs after it's reconnected?
- }
- }
-
- private class RemoteTaskListener extends ITaskListener.Stub {
- @Override
- public void onProgress(RequestId requestId, TaskResult result) throws RemoteException {
- if (DEBUG) {
- Log.v(TAG,
- String.format("RemoteTaskListener#onProgress(%s, %s)", requestId, result));
- }
-
- // TODO: implement rest.
- }
-
- @Override
- public void onComplete(RequestId requestId, TaskResult result) throws RemoteException {
- if (DEBUG) {
- Log.v(TAG,
- String.format("RemoteTaskListener#onComplete(%s, %s)", requestId, result));
- }
-
- if (mJobService != null) {
- mJobService.onIorapdTaskCompleted(requestId);
- }
-
- // TODO: implement rest.
- }
- }
-
- /** Allow passing lambdas to #invokeRemote */
- private interface RemoteRunnable {
- // TODO: run(RequestId) ?
- void run(IIorap iorap) throws RemoteException;
- }
-
- // Always pass in the iorap directly here to avoid data race.
- private static boolean invokeRemote(IIorap iorap, RemoteRunnable r) {
- if (iorap == null) {
- Log.w(TAG, "IIorap went to null in this thread, drop invokeRemote.");
- return false;
- }
- try {
- r.run(iorap);
- return true;
- } catch (RemoteException e) {
- // This could be a logic error (remote side returning error), which we need to fix.
- //
- // This could also be a DeadObjectException in which case its probably just iorapd
- // being manually restarted.
- //
- // Don't make any assumption, since DeadObjectException could also mean iorapd crashed
- // unexpectedly.
- //
- // DeadObjectExceptions are recovered from using DeathRecipient and #linkToDeath.
- handleRemoteError(e);
- return false;
- }
- }
-
- private static void handleRemoteError(Throwable t) {
- if (WTF_CRASH) {
- // In development modes, we just want to crash.
- throw new AssertionError("unexpected remote error", t);
- } else {
- // Log to wtf which gets sent to dropbox, and in system_server this does not crash.
- Log.wtf(TAG, t);
- }
- }
-
- // Encode A-Z bitstring into bits. Every character is bits.
- // Characters outside of the range [a,z] are considered out of range.
- //
- // The least significant bits hold the last character.
- // First 2 bits are left as 0.
- private static int encodeEnglishAlphabetStringIntoInt(String name) {
- int value = 0;
-
- final int CHARS_PER_INT = 6;
- final int BITS_PER_CHAR = 5;
- // Note: 2 top bits are unused, this also means our values are non-negative.
- final char CHAR_LOWER = 'a';
- final char CHAR_UPPER = 'z';
-
- if (name.length() > CHARS_PER_INT) {
- throw new IllegalArgumentException(
- "String too long. Cannot encode more than 6 chars: " + name);
- }
-
- for (int i = 0; i < name.length(); ++i) {
- char c = name.charAt(i);
-
- if (c < CHAR_LOWER || c > CHAR_UPPER) {
- throw new IllegalArgumentException("String has out-of-range [a-z] chars: " + name);
- }
-
- // Avoid sign extension during promotion.
- int cur_value = (c & 0xFFFF) - (CHAR_LOWER & 0xFFFF);
- if (cur_value >= (1 << BITS_PER_CHAR)) {
- throw new AssertionError("wtf? i=" + i + ", name=" + name);
- }
-
- value = value << BITS_PER_CHAR;
- value = value | cur_value;
- }
-
- return value;
- }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
deleted file mode 100644
index b91dd71fd28c..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.app.job.JobParameters;
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward JobService events to iorapd. <br /><br />
- *
- * iorapd sometimes need to use background jobs. Forwarding these events to iorapd
- * notifies iorapd when it is an opportune time to execute these background jobs.
- *
- * @hide
- */
-public class JobScheduledEvent implements Parcelable {
-
- /** JobService#onJobStarted */
- public static final int TYPE_START_JOB = 0;
- /** JobService#onJobStopped */
- public static final int TYPE_STOP_JOB = 1;
- private static final int TYPE_MAX = 1;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_START_JOB,
- TYPE_STOP_JOB,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
-
- /** @see JobParameters#getJobId() */
- public final int jobId;
-
- public final String packageName;
-
- public final boolean shouldUpdateVersions;
-
- /** Device is 'idle' and it's charging (plugged in). */
- public static final int SORT_IDLE_MAINTENANCE = 0;
- private static final int SORT_MAX = 0;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "SORT_" }, value = {
- SORT_IDLE_MAINTENANCE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Sort {}
-
- /**
- * Roughly corresponds to the {@code extras} fields in a JobParameters.
- */
- @Sort public final int sort;
-
- /**
- * Creates a {@link #SORT_IDLE_MAINTENANCE} event from the type and job parameters.
- *
- * Only the job ID is retained from {@code jobParams}, all other param info is dropped.
- */
- @NonNull
- public static JobScheduledEvent createIdleMaintenance(
- @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) {
- return new JobScheduledEvent(
- type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions);
- }
-
- private JobScheduledEvent(@Type int type,
- int jobId,
- @Sort int sort,
- String packageName,
- boolean shouldUpdateVersions) {
- this.type = type;
- this.jobId = jobId;
- this.sort = sort;
- this.packageName = packageName;
- this.shouldUpdateVersions = shouldUpdateVersions;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- // No check for 'jobId': any int is valid.
- CheckHelpers.checkTypeInRange(sort, SORT_MAX);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof JobScheduledEvent) {
- return equals((JobScheduledEvent) other);
- }
- return false;
- }
-
- private boolean equals(JobScheduledEvent other) {
- return type == other.type &&
- jobId == other.jobId &&
- sort == other.sort &&
- packageName.equals(other.packageName) &&
- shouldUpdateVersions == other.shouldUpdateVersions;
- }
-
- @Override
- public String toString() {
- return String.format(
- "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}",
- type, jobId, sort, packageName, shouldUpdateVersions);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- out.writeInt(jobId);
- out.writeInt(sort);
- out.writeString(packageName);
- out.writeBoolean(shouldUpdateVersions);
-
- // We do not parcel the entire JobParameters here because there is no C++ equivalent
- // of that class [which the iorapd side of the binder interface requires].
- }
-
- private JobScheduledEvent(Parcel in) {
- this.type = in.readInt();
- this.jobId = in.readInt();
- this.sort = in.readInt();
- this.packageName = in.readString();
- this.shouldUpdateVersions = in.readBoolean();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<JobScheduledEvent> CREATOR
- = new Parcelable.Creator<JobScheduledEvent>() {
- public JobScheduledEvent createFromParcel(Parcel in) {
- return new JobScheduledEvent(in);
- }
-
- public JobScheduledEvent[] newArray(int size) {
- return new JobScheduledEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
deleted file mode 100644
index aa4eea716363..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.net.Uri;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Forward package manager events to iorapd. <br /><br />
- *
- * Knowing when packages are modified by the system are a useful tidbit to help with performance:
- * for example when a package is replaced, it could be a hint used to invalidate any collected
- * io profiles used for prefetching or pinning.
- *
- * @hide
- */
-public class PackageEvent implements Parcelable {
-
- /** @see android.content.Intent#ACTION_PACKAGE_REPLACED */
- public static final int TYPE_REPLACED = 0;
- private static final int TYPE_MAX = 0;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_REPLACED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
-
- /** The path that a package is installed in, for example {@code /data/app/.../base.apk}. */
- public final Uri packageUri;
- /** The name of the package, for example {@code com.android.calculator}. */
- public final String packageName;
-
- @NonNull
- public static PackageEvent createReplaced(Uri packageUri, String packageName) {
- return new PackageEvent(TYPE_REPLACED, packageUri, packageName);
- }
-
- private PackageEvent(@Type int type, Uri packageUri, String packageName) {
- this.type = type;
- this.packageUri = packageUri;
- this.packageName = packageName;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- Objects.requireNonNull(packageUri, "packageUri");
- Objects.requireNonNull(packageName, "packageName");
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof PackageEvent) {
- return equals((PackageEvent) other);
- }
- return false;
- }
-
- private boolean equals(PackageEvent other) {
- return type == other.type &&
- Objects.equals(packageUri, other.packageUri) &&
- Objects.equals(packageName, other.packageName);
- }
-
- @Override
- public String toString() {
- return String.format("{packageUri: %s, packageName: %s}", packageUri, packageName);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- packageUri.writeToParcel(out, flags);
- out.writeString(packageName);
- }
-
- private PackageEvent(Parcel in) {
- this.type = in.readInt();
- this.packageUri = Uri.CREATOR.createFromParcel(in);
- this.packageName = in.readString();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<PackageEvent> CREATOR
- = new Parcelable.Creator<PackageEvent>() {
- public PackageEvent createFromParcel(Parcel in) {
- return new PackageEvent(in);
- }
-
- public PackageEvent[] newArray(int size) {
- return new PackageEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
deleted file mode 100644
index 503e1c633581..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.NonNull;
-
-/**
- * Uniquely identify an {@link com.google.android.startop.iorap.IIorap} method invocation,
- * used for asynchronous callbacks by the server. <br /><br />
- *
- * As all system server binder calls must be {@code oneway}, this means all invocations
- * into {@link com.google.android.startop.iorap.IIorap} are non-blocking. The request ID
- * exists to associate all calls with their respective callbacks in
- * {@link com.google.android.startop.iorap.ITaskListener}.
- *
- * @see com.google.android.startop.iorap.IIorap
- *
- * @hide
- */
-public class RequestId implements Parcelable {
-
- public final long requestId;
-
- private static Object mLock = new Object();
- private static long mNextRequestId = 0;
-
- /**
- * Create a monotonically increasing request ID.<br /><br />
- *
- * It is invalid to re-use the same request ID for multiple method calls on
- * {@link com.google.android.startop.iorap.IIorap}; a new request ID must be created
- * each time.
- */
- @NonNull public static RequestId nextValueForSequence() {
- long currentRequestId;
- synchronized (mLock) {
- currentRequestId = mNextRequestId;
- ++mNextRequestId;
- }
- return new RequestId(currentRequestId);
- }
-
- private RequestId(long requestId) {
- this.requestId = requestId;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- if (requestId < 0) {
- throw new IllegalArgumentException("request id must be non-negative");
- }
- }
-
- @Override
- public String toString() {
- return String.format("{requestId: %d}", requestId);
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(requestId);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof RequestId) {
- return equals((RequestId) other);
- }
- return false;
- }
-
- private boolean equals(RequestId other) {
- return requestId == other.requestId;
- }
-
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeLong(requestId);
- }
-
- private RequestId(Parcel in) {
- requestId = in.readLong();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<RequestId> CREATOR
- = new Parcelable.Creator<RequestId>() {
- public RequestId createFromParcel(Parcel in) {
- return new RequestId(in);
- }
-
- public RequestId[] newArray(int size) {
- return new RequestId[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
deleted file mode 100644
index 75d47f9e3d17..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward system service events to iorapd.
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceEvent implements Parcelable {
-
- /** @see com.android.server.SystemService#onBootPhase */
- public static final int TYPE_BOOT_PHASE = 0;
- /** @see com.android.server.SystemService#onStart */
- public static final int TYPE_START = 1;
- private static final int TYPE_MAX = TYPE_START;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_BOOT_PHASE,
- TYPE_START,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
-
- // TODO: do we want to pass the exact build phase enum?
-
- public SystemServiceEvent(@Type int type) {
- this.type = type;
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- }
-
- @Override
- public String toString() {
- return String.format("{type: %d}", type);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof SystemServiceEvent) {
- return equals((SystemServiceEvent) other);
- }
- return false;
- }
-
- private boolean equals(SystemServiceEvent other) {
- return type == other.type;
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- }
-
- private SystemServiceEvent(Parcel in) {
- this.type = in.readInt();
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<SystemServiceEvent> CREATOR
- = new Parcelable.Creator<SystemServiceEvent>() {
- public SystemServiceEvent createFromParcel(Parcel in) {
- return new SystemServiceEvent(in);
- }
-
- public SystemServiceEvent[] newArray(int size) {
- return new SystemServiceEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
deleted file mode 100644
index 2e7bafe7bdbf..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward user events to iorapd.<br /><br />
- *
- * Knowledge of the logged-in user is reserved to be used to set-up appropriate policies
- * by iorapd (e.g. to handle user default pinned applications changing).
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceUserEvent implements Parcelable {
-
- /** @see com.android.server.SystemService#onUserStarting */
- public static final int TYPE_START_USER = 0;
- /** @see com.android.server.SystemService#onUserUnlocking */
- public static final int TYPE_UNLOCK_USER = 1;
- /** @see com.android.server.SystemService#onUserSwitching*/
- public static final int TYPE_SWITCH_USER = 2;
- /** @see com.android.server.SystemService#onUserStopping */
- public static final int TYPE_STOP_USER = 3;
- /** @see com.android.server.SystemService#onUserStopped */
- public static final int TYPE_CLEANUP_USER = 4;
- private static final int TYPE_MAX = TYPE_CLEANUP_USER;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_START_USER,
- TYPE_UNLOCK_USER,
- TYPE_SWITCH_USER,
- TYPE_STOP_USER,
- TYPE_CLEANUP_USER,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- @Type public final int type;
- public final int userHandle;
-
- public SystemServiceUserEvent(@Type int type, int userHandle) {
- this.type = type;
- this.userHandle = userHandle;
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkTypeInRange(type, TYPE_MAX);
- if (userHandle < 0) {
- throw new IllegalArgumentException("userHandle must be non-negative");
- }
- }
-
- @Override
- public String toString() {
- return String.format("{type: %d, userHandle: %d}", type, userHandle);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof SystemServiceUserEvent) {
- return equals((SystemServiceUserEvent) other);
- }
- return false;
- }
-
- private boolean equals(SystemServiceUserEvent other) {
- return type == other.type &&
- userHandle == other.userHandle;
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(type);
- out.writeInt(userHandle);
- }
-
- private SystemServiceUserEvent(Parcel in) {
- this.type = in.readInt();
- this.userHandle = in.readInt();
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<SystemServiceUserEvent> CREATOR
- = new Parcelable.Creator<SystemServiceUserEvent>() {
- public SystemServiceUserEvent createFromParcel(Parcel in) {
- return new SystemServiceUserEvent(in);
- }
-
- public SystemServiceUserEvent[] newArray(int size) {
- return new SystemServiceUserEvent[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
deleted file mode 100644
index b5fd6d8d1c45..000000000000
--- a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Result data accompanying a request for {@link com.google.android.startop.iorap.ITaskListener}
- * callbacks.<br /><br />
- *
- * Following {@link com.google.android.startop.iorap.IIorap} method invocation,
- * iorapd will issue in-order callbacks for that corresponding {@link RequestId}.<br /><br />
- *
- * State transitions are as follows: <br /><br />
- *
- * <pre>
- * ┌─────────────────────────────┐
- * │ ▼
- * ┌───────┐ ┌─────────┐ ╔═══════════╗
- * ──▶ │ BEGAN │ ──▶ │ ONGOING │ ──▶ ║ COMPLETED ║
- * └───────┘ └─────────┘ ╚═══════════╝
- * │ │
- * │ │
- * ▼ │
- * ╔═══════╗ │
- * ──▶ ║ ERROR ║ ◀─────┘
- * ╚═══════╝
- *
- * </pre> <!-- system/iorap/docs/binder/TaskResult.dot -->
- *
- * @hide
- */
-public class TaskResult implements Parcelable {
-
- public static final int STATE_BEGAN = 0;
- public static final int STATE_ONGOING = 1;
- public static final int STATE_COMPLETED = 2;
- public static final int STATE_ERROR = 3;
- private static final int STATE_MAX = STATE_ERROR;
-
- /** @hide */
- @IntDef(flag = true, prefix = { "STATE_" }, value = {
- STATE_BEGAN,
- STATE_ONGOING,
- STATE_COMPLETED,
- STATE_ERROR,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface State {}
-
- @State public final int state;
-
- @Override
- public String toString() {
- return String.format("{state: %d}", state);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof TaskResult) {
- return equals((TaskResult) other);
- }
- return false;
- }
-
- private boolean equals(TaskResult other) {
- return state == other.state;
- }
-
- public TaskResult(@State int state) {
- this.state = state;
-
- checkConstructorArguments();
- }
-
- private void checkConstructorArguments() {
- CheckHelpers.checkStateInRange(state, STATE_MAX);
- }
-
- //<editor-fold desc="Binder boilerplate">
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(state);
- }
-
- private TaskResult(Parcel in) {
- state = in.readInt();
-
- checkConstructorArguments();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<TaskResult> CREATOR
- = new Parcelable.Creator<TaskResult>() {
- public TaskResult createFromParcel(Parcel in) {
- return new TaskResult(in);
- }
-
- public TaskResult[] newArray(int size) {
- return new TaskResult[size];
- }
- };
- //</editor-fold>
-}
diff --git a/startop/iorap/stress/Android.bp b/startop/iorap/stress/Android.bp
deleted file mode 100644
index 6e8725d091fb..000000000000
--- a/startop/iorap/stress/Android.bp
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-cc_binary {
- name: "iorap.stress.memory",
- srcs: ["main_memory.cc"],
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wno-unused-parameter"
- ],
-
- shared_libs: [
- "libbase"
- ],
-
- host_supported: true,
-}
diff --git a/startop/iorap/stress/main_memory.cc b/startop/iorap/stress/main_memory.cc
deleted file mode 100644
index 1f268619e4d9..000000000000
--- a/startop/iorap/stress/main_memory.cc
+++ /dev/null
@@ -1,126 +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.
-//
-
-#include <chrono>
-#include <fstream>
-#include <iostream>
-#include <random>
-#include <string>
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include <android-base/parseint.h>
-
-static constexpr size_t kBytesPerMb = 1048576;
-const size_t kMemoryAllocationSize = 2 * 1024 * kBytesPerMb;
-
-#define USE_MLOCKALL 0
-
-std::string GetProcessStatus(const char* key) {
- // Build search pattern of key and separator.
- std::string pattern(key);
- pattern.push_back(':');
-
- // Search for status lines starting with pattern.
- std::ifstream fs("/proc/self/status");
- std::string line;
- while (std::getline(fs, line)) {
- if (strncmp(pattern.c_str(), line.c_str(), pattern.size()) == 0) {
- // Skip whitespace in matching line (if any).
- size_t pos = line.find_first_not_of(" \t", pattern.size());
- if (pos == std::string::npos) {
- break;
- }
- return std::string(line, pos);
- }
- }
- return "<unknown>";
-}
-
-int main(int argc, char** argv) {
- size_t allocationSize = 0;
- if (argc >= 2) {
- if (!android::base::ParseUint(argv[1], /*out*/&allocationSize)) {
- std::cerr << "Failed to parse the allocation size (must be 0,MAX_SIZE_T)" << std::endl;
- return 1;
- }
- } else {
- allocationSize = kMemoryAllocationSize;
- }
-
- void* mem = malloc(allocationSize);
- if (mem == nullptr) {
- std::cerr << "Malloc failed" << std::endl;
- return 1;
- }
-
- volatile int* imem = static_cast<int *>(mem); // don't optimize out memory usage
-
- size_t imemCount = allocationSize / sizeof(int);
-
- std::cout << "Allocated " << allocationSize << " bytes" << std::endl;
-
- auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
- std::mt19937 mt_rand(seed);
-
- size_t randPrintCount = 10;
-
- // Write random numbers:
- // * Ensures each page is resident
- // * Avoids zeroed out pages (zRAM)
- // * Avoids same-page merging
- for (size_t i = 0; i < imemCount; ++i) {
- imem[i] = mt_rand();
-
- if (i < randPrintCount) {
- std::cout << "Generated random value: " << imem[i] << std::endl;
- }
- }
-
-#if USE_MLOCKALL
- /*
- * Lock all pages from the address space of this process.
- */
- if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
- std::cerr << "Mlockall failed" << std::endl;
- return 1;
- }
-#else
- // Use mlock because of the predictable VmLck size.
- // Using mlockall tends to bring in anywhere from 2-2.5GB depending on the device.
- if (mlock(mem, allocationSize) != 0) {
- std::cerr << "Mlock failed" << std::endl;
- return 1;
- }
-#endif
-
- // Validate memory is actually resident and locked with:
- // $> cat /proc/$(pidof iorap.stress.memory)/status | grep VmLck
- std::cout << "Locked memory (VmLck) = " << GetProcessStatus("VmLck") << std::endl;
-
- std::cout << "Press any key to terminate" << std::endl;
- int any_input;
- std::cin >> any_input;
-
- std::cout << "Terminating..." << std::endl;
-
- munlockall();
- free(mem);
-
- return 0;
-}
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
deleted file mode 100644
index ad3d001ad7d4..000000000000
--- a/startop/iorap/tests/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// TODO: once b/80095087 is fixed, rewrite this back to android_test
-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"],
-}
-
-java_library {
- name: "libiorap-java-test-lib",
- srcs: ["src/**/*.kt"],
- static_libs: [
- // Non-test dependencies
- // library under test
- "services.startop.iorap",
- // need the system_server code to be on the classpath,
- "services.core",
- // Test Dependencies
- // test android dependencies
- "platform-test-annotations",
- "androidx.test.rules",
- // test framework dependencies
- "mockito-target-inline-minus-junit4",
- // "mockito-target-minus-junit4",
- // Mockito also requires JNI (see Android.mk)
- // and android:debuggable=true (see AndroidManifest.xml)
- "truth-prebuilt",
- ],
- // sdk_version: "current",
- // certificate: "platform",
- libs: [
- "android.test.base",
- "android.test.runner",
- ],
- // test_suites: ["device-tests"],
-}
-
-android_test {
- name: "libiorap-java-tests",
- dxflags: ["--multi-dex"],
- test_suites: ["device-tests"],
- static_libs: ["libiorap-java-test-lib"],
- compile_multilib: "both",
- jni_libs: [
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
- "libmultiplejvmtiagentsinterferenceagent",
- ],
- libs: [
- "android.test.base",
- "android.test.runner",
- ],
- // Use private APIs
- certificate: "platform",
- platform_apis: true,
-}
diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml
deleted file mode 100644
index b967e7207a3f..000000000000
--- a/startop/iorap/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.google.android.startop.iorap.tests"
- android:sharedUserId="com.google.android.startop.iorap.tests"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <!--suppress AndroidDomInspection -->
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.google.android.startop.iorap.tests" />
-
- <!--
- 'debuggable=true' is required to properly load mockito jvmti dependencies,
- otherwise it gives the following error at runtime:
-
- Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
- Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
- <application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
- </application>
-</manifest>
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
deleted file mode 100644
index 6102c44e61bf..000000000000
--- a/startop/iorap/tests/AndroidTest.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<configuration description="Runs libiorap-java-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="test-file-name" value="libiorap-java-tests.apk" />
- </target_preparer>
-
- <!--
- Our IIorapIntegrationTest.kt requires setlinux to be disabled:
- it connects to the iorapd binder service but this requires selinux permissions:
-
- avc: denied { find } for service=iorapd pid=2738 uid=10050
- scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0
- tclass=service_manager permissive=0
- -->
- <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
- </target_preparer>
-
- <!-- do not use DeviceSetup#set-property because it reboots the device b/136200738.
- furthermore the changes in /data/local.prop don't actually seem to get picked up.
- -->
- <target_preparer
- class="com.android.tradefed.targetprep.DeviceSetup">
- <!-- we need this magic flag, otherwise it always reboots and breaks the selinux -->
- <option name="force-skip-system-props" value="true" />
-
- <!-- Crash instead of using Log.wtf within the system_server iorap code. -->
- <option name="run-command" value="setprop iorapd.forwarding_service.wtf_crash true" />
- <!-- IIorapd has fake behavior: it doesn't do anything but reply with 'DONE' status -->
- <option name="run-command" value="setprop iorapd.binder.fake true" />
-
- <!-- iorapd does not pick up the above changes until we restart it -->
- <option name="run-command" value="stop iorapd" />
- <option name="run-command" value="start iorapd" />
- <!-- give it some time to restart the service; otherwise the first unit test might fail -->
- <option name="run-command" value="sleep 1" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.google.android.startop.iorap.tests" />
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- </test>
-
- <!-- using DeviceSetup again does not work. we simply leave the device in a semi-bad
- state. there is no way to clean this up as far as I know.
- -->
-
-</configuration>
-
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
deleted file mode 100644
index 51e407d4cbff..000000000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
+++ /dev/null
@@ -1,181 +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 com.google.android.startop.iorap
-
-import android.content.Intent;
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import com.google.android.startop.iorap.AppLaunchEvent;
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunched
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchCancelled
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchFinished
-import com.google.android.startop.iorap.AppLaunchEvent.IntentStarted;
-import com.google.android.startop.iorap.AppLaunchEvent.IntentFailed;
-import com.google.android.startop.iorap.AppLaunchEvent.ReportFullyDrawn
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-
-/**
- * Basic unit tests to test all of the [AppLaunchEvent]s in [com.google.android.startop.iorap].
- */
-@SmallTest
-class AppLaunchEventTest {
- /**
- * Test for IntentStarted.
- */
- @Test
- fun testIntentStarted() {
- var intent = Intent()
- val valid = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
- val copy = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
- val noneCopy1 = IntentStarted(/* sequenceId= */1L, intent, /* timestampNs= */ 1L)
- val noneCopy2 = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 2L)
- val noneCopy3 = IntentStarted(/* sequenceId= */2L, Intent(), /* timestampNs= */ 1L)
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy1)
- assertThat(valid).isNotEqualTo(noneCopy2)
- assertThat(valid).isNotEqualTo(noneCopy3)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("IntentStarted{sequenceId=2, intent=Intent { } , timestampNs=1}")
- }
-
- /**
- * Test for IntentFailed.
- */
- @Test
- fun testIntentFailed() {
- val valid = IntentFailed(/* sequenceId= */2L)
- val copy = IntentFailed(/* sequenceId= */2L)
- val noneCopy = IntentFailed(/* sequenceId= */1L)
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("IntentFailed{sequenceId=2}")
- }
-
- /**
- * Test for ActivityLaunched.
- */
- @Test
- fun testActivityLaunched() {
- //var activityRecord =
- val valid = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
- /* temperature= */ 0)
- val copy = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
- /* temperature= */ 0)
- val noneCopy1 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
- /* temperature= */ 0)
- val noneCopy2 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
- /* temperature= */ 1)
- val noneCopy3 = ActivityLaunched(/* sequenceId= */1L, "test1".toByteArray(),
- /* temperature= */ 0)
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy1)
- assertThat(valid).isNotEqualTo(noneCopy2)
- assertThat(valid).isNotEqualTo(noneCopy3)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("ActivityLaunched{sequenceId=2, test, temperature=0}")
- }
-
-
- /**
- * Test for ActivityLaunchFinished.
- */
- @Test
- fun testActivityLaunchFinished() {
- val valid = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
- /* timestampNs= */ 1L)
- val copy = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
- /* timestampNs= */ 1L)
- val noneCopy1 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
- /* timestampNs= */ 1L)
- val noneCopy2 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
- /* timestampNs= */ 2L)
- val noneCopy3 = ActivityLaunchFinished(/* sequenceId= */2L, "test1".toByteArray(),
- /* timestampNs= */ 1L)
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy1)
- assertThat(valid).isNotEqualTo(noneCopy2)
- assertThat(valid).isNotEqualTo(noneCopy3)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("ActivityLaunchFinished{sequenceId=2, test, timestampNs=1}")
- }
-
- /**
- * Test for ActivityLaunchCancelled.
- */
- @Test
- fun testActivityLaunchCancelled() {
- val valid = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
- val copy = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
- val noneCopy1 = ActivityLaunchCancelled(/* sequenceId= */1L, "test".toByteArray())
- val noneCopy2 = ActivityLaunchCancelled(/* sequenceId= */2L, "test1".toByteArray())
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy1)
- assertThat(valid).isNotEqualTo(noneCopy2)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("ActivityLaunchCancelled{sequenceId=2, test}")
- }
-
- /**
- * Test for ReportFullyDrawn.
- */
- @Test
- fun testReportFullyDrawn() {
- val valid = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
- val copy = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
- val noneCopy1 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
- /* timestampNs= */ 1L)
- val noneCopy2 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
- /* timestampNs= */ 1L)
- val noneCopy3 = ReportFullyDrawn(/* sequenceId= */2L, "test1".toByteArray(),
- /* timestampNs= */ 1L)
-
- // equals(Object other)
- assertThat(valid).isEqualTo(copy)
- assertThat(valid).isNotEqualTo(noneCopy1)
- assertThat(valid).isNotEqualTo(noneCopy2)
- assertThat(valid).isNotEqualTo(noneCopy3)
-
- // test toString()
- val result = valid.toString()
- assertThat(result).isEqualTo("ReportFullyDrawn{sequenceId=2, test, timestampNs=1}")
- }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
deleted file mode 100644
index 18c249136d05..000000000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.ServiceManager
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.MediumTest
-import org.junit.Test
-import org.mockito.Mockito.argThat
-import org.mockito.Mockito.eq
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.timeout
-
-// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
-@MediumTest
-@FlakyTest(bugId = 149098310) // Failing on cuttlefish with SecurityException.
-class IIorapIntegrationTest {
- /**
- * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
- */
- private val iorapService: IIorap by lazy {
- // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
- IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
-
- // Use 'adb shell setenforce 0' otherwise this whole test fails,
- // because the servicemanager is not allowed to hand out the binder token for iorapd.
-
- // TODO: implement the selinux policies for iorapd.
- }
-
- // A dummy binder stub implementation is required to use with mockito#spy.
- // Mockito overrides the methods at runtime and tracks how methods were invoked.
- open class DummyTaskListener : ITaskListener.Stub() {
- // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
- // from using the mockito matchers (eq, argThat, etc).
- override fun onProgress(requestId: RequestId?, result: TaskResult?) {
- }
-
- override fun onComplete(requestId: RequestId?, result: TaskResult?) {
- }
- }
-
- private fun testAnyMethod(func: (RequestId) -> Unit) {
- val taskListener = spy(DummyTaskListener())!!
-
- // FIXME: b/149098310
- return
-
- try {
- iorapService.setTaskListener(taskListener)
- // Note: Binder guarantees total order for oneway messages sent to the same binder
- // interface, so we don't need any additional blocking here before sending later calls.
-
- // Every new method call should have a unique request id.
- val requestId = RequestId.nextValueForSequence()!!
-
- // Apply the specific function under test.
- func(requestId)
-
- // Typical mockito behavior is to allow any-order callbacks, but we want to test order.
- val inOrder = inOrder(taskListener)
-
- // The "stub" behavior of iorapd is that every request immediately gets a response of
- // BEGAN,ONGOING,COMPLETED
- inOrder.verify(taskListener, timeout(100))
- .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
- inOrder.verify(taskListener, timeout(100))
- .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
- inOrder.verify(taskListener, timeout(100))
- .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
- inOrder.verifyNoMoreInteractions()
- } finally {
- // iorapService.setTaskListener(null)
- // FIXME: null is broken, C++ side sees a non-null object.
- }
- }
-
- @Test
- fun testOnPackageEvent() {
- // FIXME (b/137134253): implement PackageEvent parsing on the C++ side.
- // This is currently (silently: b/137135024) failing because IIorap is 'oneway' and the
- // C++ PackageEvent un-parceling fails since its not implemented fully.
- /*
- testAnyMethod { requestId : RequestId ->
- iorapService.onPackageEvent(requestId,
- PackageEvent.createReplaced(
- Uri.parse("https://www.google.com"), "com.fake.package"))
- }
- */
- }
-
- @Test
- fun testOnAppIntentEvent() {
- testAnyMethod { requestId: RequestId ->
- iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
- ActivityInfo("dont care", "dont care"),
- ActivityInfo("dont care 2", "dont care 2")))
- }
- }
-
- @Test
- fun testOnAppLaunchEvent() {
- testAnyMethod { requestId : RequestId ->
- iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentFailed(/*sequenceId*/123))
- }
- }
-
- @Test
- fun testOnSystemServiceEvent() {
- testAnyMethod { requestId: RequestId ->
- iorapService.onSystemServiceEvent(requestId,
- SystemServiceEvent(SystemServiceEvent.TYPE_START))
- }
- }
-
- @Test
- fun testOnSystemServiceUserEvent() {
- testAnyMethod { requestId: RequestId ->
- iorapService.onSystemServiceUserEvent(requestId,
- SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0))
- }
- }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
deleted file mode 100644
index 150577a21f5a..000000000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
-import org.junit.runners.Parameterized
-
-/**
- * Basic unit tests to ensure that all of the [Parcelable]s in [com.google.android.startop.iorap]
- * have a valid-conforming interface implementation.
- */
-@SmallTest
-@RunWith(Parameterized::class)
-class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) {
- companion object {
- private val initialRequestId = RequestId.nextValueForSequence()!!
-
- @JvmStatic
- @Parameterized.Parameters
- fun data() = listOf(
- InputData(
- newActivityInfo(),
- newActivityInfo(),
- ActivityInfo("some package", "some other activity")),
- InputData(
- ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
- ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
- ActivityHintEvent(ActivityHintEvent.TYPE_POST_COMPLETED,
- newActivityInfo())),
- InputData(
- AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
- newActivityInfoOther()),
- AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
- newActivityInfoOther()),
- AppIntentEvent.createDefaultIntentChanged(newActivityInfoOther(),
- newActivityInfo())),
- InputData(
- PackageEvent.createReplaced(newUri(), "some package"),
- PackageEvent.createReplaced(newUri(), "some package"),
- PackageEvent.createReplaced(newUri(), "some other package")
- ),
- InputData(initialRequestId, cloneRequestId(initialRequestId),
- RequestId.nextValueForSequence()),
- InputData(
- SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
- SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
- SystemServiceEvent(SystemServiceEvent.TYPE_START)),
- InputData(
- SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
- SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
- SystemServiceUserEvent(SystemServiceUserEvent.TYPE_CLEANUP_USER, 12345)),
- InputData(
- TaskResult(TaskResult.STATE_COMPLETED),
- TaskResult(TaskResult.STATE_COMPLETED),
- TaskResult(TaskResult.STATE_ONGOING))
- )
-
- private fun newActivityInfo(): ActivityInfo {
- return ActivityInfo("some package", "some activity")
- }
-
- private fun newActivityInfoOther(): ActivityInfo {
- return ActivityInfo("some package 2", "some activity 2")
- }
-
- private fun newUri(): Uri {
- return Uri.parse("https://www.google.com")
- }
-
- private fun cloneRequestId(requestId: RequestId): RequestId {
- val constructor = requestId::class.java.declaredConstructors[0]
- constructor.isAccessible = true
- return constructor.newInstance(requestId.requestId) as RequestId
- }
- }
-
- /**
- * Test for [Object.equals] implementation.
- */
- @Test
- fun testEquality() {
- assertThat(inputData.valid).isEqualTo(inputData.valid)
- assertThat(inputData.valid).isEqualTo(inputData.validCopy)
- assertThat(inputData.valid).isNotEqualTo(inputData.validOther)
- }
-
- /**
- * Test for [Parcelable] implementation.
- */
- @Test
- fun testParcelRoundTrip() {
- // calling writeToParcel and then T::CREATOR.createFromParcel would return the same data.
- val assertParcels = { it: T, data: InputData<T> ->
- val parcel = Parcel.obtain()
- it.writeToParcel(parcel, 0)
- parcel.setDataPosition(0) // future reads will see all previous writes.
- assertThat(it).isEqualTo(data.createFromParcel(parcel))
- parcel.recycle()
- }
-
- assertParcels(inputData.valid, inputData)
- assertParcels(inputData.validCopy, inputData)
- assertParcels(inputData.validOther, inputData)
- }
-
- data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) {
- val kls = valid.javaClass
- init {
- assertThat(valid).isNotSameInstanceAs(validCopy)
- // Don't use isInstanceOf because of phantom warnings in intellij about Class!
- assertThat(validCopy.javaClass).isEqualTo(valid.javaClass)
- assertThat(validOther.javaClass).isEqualTo(valid.javaClass)
- }
-
- fun createFromParcel(parcel: Parcel): T {
- val field = kls.getDeclaredField("CREATOR")
- val creator = field.get(null) as Parcelable.Creator<T>
-
- return creator.createFromParcel(parcel)
- }
- }
-}
diff --git a/startop/scripts/app_startup/analyze_metrics.py b/startop/scripts/app_startup/analyze_metrics.py
deleted file mode 100755
index d74d6f68d823..000000000000
--- a/startop/scripts/app_startup/analyze_metrics.py
+++ /dev/null
@@ -1,457 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Perform statistical analysis on measurements produced by app_startup_runner.py
-
-Install:
-$> sudo apt-get install python3-scipy
-
-Usage:
-$> ./analyze_metrics.py <filename.csv> [<filename2.csv> ...]
-$> ./analyze_metrics.py --help
-"""
-
-import argparse
-import csv
-import itertools
-import os
-import subprocess
-import sys
-import tempfile
-from typing import Any, List, Dict, Iterable, TextIO, Tuple
-
-from scipy import stats as sc
-import numpy as np
-
-
-# These CSV columns are considered labels. Everything after them in the same row are metrics.
-_LABEL_COLUMNS=['packages', 'readaheads', 'compiler_filters']
-# The metric series with the 'cold' readahead is the baseline.
-# All others (warm, jit, etc) are the potential improvements.
-
-#fixme: this should probably be an option
-_BASELINE=('readaheads', 'cold')
-# ignore this for some statistic calculations
-_IGNORE_PAIR=('readaheads', 'warm')
-_PLOT_SUBKEY='readaheads'
-_PLOT_GROUPKEY='packages'
-_PLOT_DATA_INDEX = 0
-_DELTA=50
-_DELTA2=100
-_PVALUE_THRESHOLD=0.10
-_debug = False # See -d/--debug flag.
-
-def parse_options(argv: List[str] = None):
- """Parse command line arguments and return an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Perform statistical analysis on measurements produced by app_start_runner.py.")
- parser.add_argument('input_files', metavar='file.csv', nargs='+', help='CSV file produced by app_startup_runner.py')
-
- parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
- parser.add_argument('-os', '--output-samples', dest='output_samples', default='/dev/null', action='store', help='Store CSV for per-sample data')
- parser.add_argument('-oc', '--output-comparable', dest='output_comparable', default='/dev/null', action='store', help='Output CSV for comparable against baseline')
- parser.add_argument('-ocs', '--output-comparable-significant', dest='output_comparable_significant', default='/dev/null', action='store', help='Output CSV for comparable against baseline (significant only)')
- parser.add_argument('-pt', '--pvalue-threshold', dest='pvalue_threshold', type=float, default=_PVALUE_THRESHOLD, action='store')
- parser.add_argument('-dt', '--delta-threshold', dest='delta_threshold', type=int, default=_DELTA, action='store')
-
- return parser.parse_args(argv)
-
-def _debug_print(*args, **kwargs):
- """Print the args to sys.stderr if the --debug/-d flag was passed in."""
- global _debug
- if _debug:
- print(*args, **kwargs, file=sys.stderr)
-
-def _expand_gen_repr(args):
- new_args_list = []
- for i in args:
- # detect iterable objects that do not have their own override of __str__
- if hasattr(i, '__iter__'):
- to_str = getattr(i, '__str__')
- if to_str.__objclass__ == object:
- # the repr for a generator is just type+address, expand it out instead.
- new_args_list.append([_expand_gen_repr([j])[0] for j in i])
- continue
- # normal case: uses the built-in to-string
- new_args_list.append(i)
- return new_args_list
-
-def _debug_print_gen(*args, **kwargs):
- """Like _debug_print but will turn any iterable args into a list."""
- if not _debug:
- return
-
- new_args_list = _expand_gen_repr(args)
- _debug_print(*new_args_list, **kwargs)
-
-def read_headers(input_file: TextIO) -> Tuple[List[str], List[str]]:
- _debug_print("read_headers for file: ", input_file.name)
- csv_reader = csv.reader(input_file)
-
- label_num_columns = len(_LABEL_COLUMNS)
-
- try:
- header = next(csv_reader)
- except StopIteration:
- header = None
- _debug_print('header', header)
-
- if not header:
- return (None, None)
-
- labels = header[0:label_num_columns]
- data = header[label_num_columns:]
-
- return (labels, data)
-
-def read_labels_and_data(input_file: TextIO) -> Iterable[Tuple[List[str], List[int]]]:
- _debug_print("print_analysis for file: ", input_file.name)
- csv_reader = csv.reader(input_file)
-
- # Skip the header because it doesn't contain any data.
- # To get the header see read_headers function.
- try:
- header = next(csv_reader)
- except StopIteration:
- header = None
-
- label_num_columns = len(_LABEL_COLUMNS)
-
- for row in csv_reader:
- if len(row) > 0 and row[0][0] == ';':
- _debug_print("skip comment line", row)
- continue
-
- labels = row[0:label_num_columns]
- data = [int(i) for i in row[label_num_columns:]]
-
-# _debug_print("labels:", labels)
-# _debug_print("data:", data)
-
- yield (labels, data)
-
-def group_metrics_by_label(it: Iterable[Tuple[List[str], List[int]]]):
- prev_labels = None
- data_2d = []
-
- for label_list, data_list in it:
- if prev_labels != label_list:
- if prev_labels:
-# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
- yield (prev_labels, data_2d)
- data_2d = []
-
- data_2d.append(data_list)
- prev_labels = label_list
-
- if prev_labels:
-# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
- yield (prev_labels, data_2d)
-
-def data_to_numpy(it: Iterable[Tuple[List[str], List[List[int]]]]) -> Iterable[Tuple[List[str], Any]]:
- for label_list, data_2d in it:
- yield (label_list, np.asarray(data_2d, dtype=int))
-
-def iterate_columns(np_data_2d):
- for col in range(np_data_2d.shape[1]):
- col_as_array = np_data_2d[:, col]
- yield col_as_array
-
-def confidence_interval(np_data_2d, percent=0.95):
- """
- Given some data [[a,b,c],[d,e,f,]...]
-
- We assume the same metric is in the column (e.g. [a,d])
- and that data in the rows (e.g. [b,e]) are separate metric values.
-
- We then calculate the CI for each metric individually returning it as a list of tuples.
- """
- arr = []
- for col_2d in iterate_columns(np_data_2d):
- mean = col_2d.mean()
- sigma = col_2d.std()
-
- ci = sc.norm.interval(percent, loc=mean, scale=sigma / np.sqrt(len(col_2d)))
- arr.append(ci)
-
- # TODO: This seems to be returning NaN when all the samples have the same exact value
- # (e.g. stddev=0, which can trivially happen when sample count = 1).
-
- return arr
-
-def print_analysis(it, label_header: List[str], data_header: List[str], output_samples: str):
- print(label_header)
-
- with open(output_samples, "w") as output_file:
-
- csv_writer = csv.writer(output_file)
- csv_writer.writerow(label_header + ['mean', 'std', 'confidence_interval_a', 'confidence_interval_b'])
-
- for label_list, np_data_2d in it:
- print("**********************")
- print(label_list)
- print()
- print(" ", data_header)
- # aggregate computation column-wise
- print("Mean: ", np_data_2d.mean(axis=0))
- print("Std: ", np_data_2d.std(axis=0))
- print("CI95%:", confidence_interval(np_data_2d))
- print("SEM: ", stats_standard_error_one(np_data_2d, axis=0))
-
- #ci = confidence_interval(np_data_2d)[_PLOT_DATA_INDEX]
- sem = stats_standard_error_one(np_data_2d, axis=0)[_PLOT_DATA_INDEX]
- mean = np_data_2d.mean(axis=0)[_PLOT_DATA_INDEX]
-
- ci = (mean - sem, mean + sem)
-
- csv_writer.writerow(label_list + [mean, np_data_2d.std(axis=0)[_PLOT_DATA_INDEX], ci[0], ci[1]])
-
-def from_file_group_by_labels(input_file):
- (label_header, data_header) = read_headers(input_file)
- label_data_iter = read_labels_and_data(input_file)
- grouped_iter = group_metrics_by_label(label_data_iter)
- grouped_numpy_iter = data_to_numpy(grouped_iter)
-
- return grouped_numpy_iter, label_header, data_header
-
-def list_without_index(list, index):
- return list[:index] + list[index+1:]
-
-def group_by_without_baseline_key(grouped_numpy_iter, label_header):
- """
- Data is considered comparable if the only difference is the baseline key
- (i.e. the readahead is different but the package, compilation filter, etc, are the same).
-
- Returns iterator that's grouped by the non-baseline labels to an iterator of
- (label_list, data_2d).
- """
- baseline_index = label_header.index(_BASELINE[0])
-
- def get_label_without_baseline(tpl):
- label_list, _ = tpl
- return list_without_index(label_list, baseline_index)
- # [['pkgname', 'compfilter', 'warm'], [data]]
- # [['pkgname', 'compfilter', 'cold'], [data2]]
- # [['pkgname2', 'compfilter', 'warm'], [data3]]
- #
- # ->
- # ( [['pkgname', 'compfilter', 'warm'], [data]] # ignore baseline label change.
- # [['pkgname', 'compfilter', 'cold'], [data2]] ), # split here because the pkgname changed.
- # ( [['pkgname2', 'compfilter', 'warm'], [data3]] )
- for group_info, it in itertools.groupby(grouped_numpy_iter, key = get_label_without_baseline):
- yield it
-
- # TODO: replace this messy manual iteration/grouping with pandas
-
-def iterate_comparable_metrics(without_baseline_iter, label_header):
- baseline_index = label_header.index(_BASELINE[0])
- baseline_value = _BASELINE[1]
-
- _debug_print("iterate comparables")
-
- def is_baseline_fun(tp):
- ll, dat = tp
- return ll[baseline_index] == baseline_value
-
- # iterating here when everything but the baseline key is the same.
- for it in without_baseline_iter:
- it1, it2 = itertools.tee(it)
-
- # find all the baseline data.
- baseline_filter_it = filter(is_baseline_fun, it1)
-
- # find non-baseline data.
- nonbaseline_filter_it = itertools.filterfalse(is_baseline_fun, it2)
-
- yield itertools.product(baseline_filter_it, nonbaseline_filter_it)
-
-def stats_standard_error_one(a, axis):
- a_std = a.std(axis=axis, ddof=0)
- a_len = a.shape[axis]
-
- return a_std / np.sqrt(a_len)
-
-def stats_standard_error(a, b, axis):
- a_std = a.std(axis=axis, ddof=0)
- b_std = b.std(axis=axis, ddof=0)
-
- a_len = a.shape[axis]
- b_len = b.shape[axis]
-
- temp1 = a_std*a_std/a_len
- temp2 = b_std*b_std/b_len
-
- return np.sqrt(temp1 + temp2)
-
-def stats_tvalue(a, b, axis, delta = 0):
- a_mean = a.mean(axis=axis)
- b_mean = b.mean(axis=axis)
-
- return (a_mean - b_mean - delta) / stats_standard_error(a, b, axis)
-
-def stats_pvalue(a, b, axis, delta, left:bool = False):
- """
- Single-tailed 2-sample t-test.
-
- Returns p-value for the null hypothesis: mean(a) - mean(b) >= delta.
- :param a: numpy 2d array
- :param b: numpy 2d array
- :param axis: which axis to do the calculations across
- :param delta: test value of mean differences
- :param left: if true then use <= delta instead of >= delta
- :return: p-value
- """
- # implement our own pvalue calculation because the built-in t-test (t,p values)
- # only offer delta=0 , e.g. m1-m1 ? 0
- # we are however interested in m1-m2 ? delta
- t_value = stats_tvalue(a, b, axis, delta)
-
- # 2-sample degrees of freedom is using the array sizes - 2.
- dof = a.shape[axis] + b.shape[axis] - 2
-
- if left:
- # left tailed test. e.g. m1-m2 <= delta
- return sc.t.cdf(t_value, dof)
- else:
- # right tailed test. e.g. m1-m2 >= delta
- return sc.t.sf(t_value, dof)
- # a left+right tailed test is a 2-tail t-test and can be done using ttest_ind for delta=0
-
-def print_comparable_analysis(comparable_metrics_iter, label_header, data_header, output_comparable: str, output_comparable_significant: str):
- baseline_value = _BASELINE[1]
- baseline_index = label_header.index(_BASELINE[0])
-
- old_baseline_label_list = None
- delta = _DELTA
- filter_value = _IGNORE_PAIR[1]
- filter_index = label_header.index(_IGNORE_PAIR[0])
-
- pvalue_threshold = _PVALUE_THRESHOLD
- ci_threshold = (1 - _PVALUE_THRESHOLD) * 100.0
-
- with open(output_comparable, "w") as output_file:
-
- csv_writer = csv.writer(output_file)
- csv_writer.writerow(label_header + ['mean', 'mean_diff', 'sem', 'pvalue_2tailed', 'pvalue_gt%d' %(_DELTA), 'pvalue_gt%d' %(_DELTA2)])
-
- print("------------------------------------------------------------------")
- print("Comparison against the baseline %s = %s" %(_BASELINE, baseline_value))
- print("--- Right-tailed t-test checks if the baseline >= current %s by at least %d" %(_BASELINE[0], delta))
- print()
-
- global_stats = {'better_than_delta': [], 'better_than_delta_p95': []}
-
- for nested_it in comparable_metrics_iter:
- print("************************")
-
- better_than_delta = []
- better_than_delta_p95 = []
-
- saw_baseline_once = False
-
- for ((baseline_label_list, baseline_np_data_2d), (rest_label_list, rest_np_data_2d)) in nested_it:
- _debug_print("baseline_label_list:", baseline_label_list)
- _debug_print("baseline_np_data_2d:", baseline_np_data_2d)
- _debug_print("rest_label_list:", rest_label_list)
- _debug_print("rest_np_data_2d:", rest_np_data_2d)
-
- mean_diff = baseline_np_data_2d.mean(axis=0) - rest_np_data_2d.mean(axis=0)
- # 2-sample 2-tailed t-test with delta=0
- # e.g. "Is it true that usually the two sample means are different?"
- t_statistic, t_pvalue = sc.ttest_ind(baseline_np_data_2d, rest_np_data_2d, axis=0)
-
- # 2-sample 1-tailed t-test with delta=50
- # e.g. "Is it true that usually the sample means better than 50ms?"
- t2 = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
- p2 = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
-
- t2_b = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
- p2_b = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
-
- print("%s vs %s" %(rest_label_list, baseline_value))
- print(" ", data_header)
- print("Mean Difference: ", mean_diff)
- print("T-test (2-tailed) != 0: t=%s, p=%s" %(t_statistic, t_pvalue))
- print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA, t2, p2))
- print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA2, t2_b, p2_b))
-
- def write_out_values(label_list, *args):
- csv_writer.writerow(label_list + [i[_PLOT_DATA_INDEX] for i in args])
-
- sem = stats_standard_error(baseline_np_data_2d, rest_np_data_2d, axis=0)
- if saw_baseline_once == False:
- saw_baseline_once = True
- base_sem = stats_standard_error_one(baseline_np_data_2d, axis=0)
- write_out_values(baseline_label_list, baseline_np_data_2d.mean(axis=0), [0], base_sem, [None], [None], [None])
- write_out_values(rest_label_list, rest_np_data_2d.mean(axis=0), mean_diff, sem, t_pvalue, p2, p2_b)
-
- # now do the global statistics aggregation
-
- if rest_label_list[filter_index] == filter_value:
- continue
-
- if mean_diff > delta:
- better_than_delta.append((mean_diff, p2, rest_label_list))
-
- if p2 <= pvalue_threshold:
- better_than_delta_p95.append((mean_diff, rest_label_list))
-
- if better_than_delta:
- global_stats['better_than_delta'].append(better_than_delta)
- if better_than_delta_p95:
- global_stats['better_than_delta_p95'].append(better_than_delta_p95)
-
- print("------------------------")
- print("Global statistics:")
- print("//// Rows with %s=%s are ignored here." %_IGNORE_PAIR)
- print("- # of results with mean diff better than delta(%d) = %d" %(delta, len(global_stats['better_than_delta'])))
- print(" > (meandiff, pvalue, labels)")
- for i in global_stats['better_than_delta']:
- print(" > %s" %i)
- print("- # of results with mean diff better than delta(%d) CI%d%% = %d" %(delta, ci_threshold, len(global_stats['better_than_delta_p95'])))
- print(" > (meandiff, labels)")
- for i in global_stats['better_than_delta_p95']:
- print(" > %s" %i)
-
-def main():
- global _debug
- global _DELTA
- global _PVALUE_THRESHOLD
-
- opts = parse_options()
- _debug = opts.debug
- _debug_print("parsed options: ", opts)
-
- _PVALUE_THRESHOLD = opts.pvalue_threshold or _PVALUE_THRESHOLD
-
- for file_name in opts.input_files:
- with open(file_name, 'r') as input_file:
- (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
- print_analysis(grouped_numpy_iter, label_header, data_header, opts.output_samples)
-
- with open(file_name, 'r') as input_file:
- (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
- without_baseline_iter = group_by_without_baseline_key(grouped_numpy_iter, label_header)
- #_debug_print_gen(without_baseline_iter)
-
- comparable_metrics_iter = iterate_comparable_metrics(without_baseline_iter, label_header)
- print_comparable_analysis(comparable_metrics_iter, label_header, data_header, opts.output_comparable, opts.output_comparable_significant)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner.py b/startop/scripts/app_startup/app_startup_runner.py
deleted file mode 100755
index 25ee6f7368c8..000000000000
--- a/startop/scripts/app_startup/app_startup_runner.py
+++ /dev/null
@@ -1,393 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-#
-# Measure application start-up time by launching applications under various combinations.
-# See --help for more details.
-#
-#
-# Sample usage:
-# $> ./app_startup_runner.py -p com.google.android.calculator -r warm -r cold -lc 10 -o out.csv
-# $> ./analyze_metrics.py out.csv
-#
-#
-
-import argparse
-import csv
-import itertools
-import os
-import sys
-import tempfile
-from datetime import timedelta
-from typing import Any, Callable, Iterable, List, NamedTuple, TextIO, Tuple, \
- TypeVar, Union, Optional
-
-# local import
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-from app_startup.run_app_with_prefetch import PrefetchAppRunner
-import app_startup.lib.args_utils as args_utils
-from app_startup.lib.data_frame import DataFrame
-from app_startup.lib.perfetto_trace_collector import PerfettoTraceCollector
-from iorap.compiler import CompilerType
-import iorap.compiler as compiler
-
-# The following command line options participate in the combinatorial generation.
-# All other arguments have a global effect.
-_COMBINATORIAL_OPTIONS = ['package', 'readahead', 'compiler_filter',
- 'activity', 'trace_duration']
-_TRACING_READAHEADS = ['mlock', 'fadvise']
-_FORWARD_OPTIONS = {'loop_count': '--count'}
-_RUN_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)),
- 'run_app_with_prefetch.py')
-
-CollectorPackageInfo = NamedTuple('CollectorPackageInfo',
- [('package', str), ('compiler_filter', str)])
-# by 2; systrace starts up slowly.
-
-_UNLOCK_SCREEN_SCRIPT = os.path.join(
- os.path.dirname(os.path.realpath(__file__)), 'unlock_screen')
-
-RunCommandArgs = NamedTuple('RunCommandArgs',
- [('package', str),
- ('readahead', str),
- ('activity', Optional[str]),
- ('compiler_filter', Optional[str]),
- ('timeout', Optional[int]),
- ('debug', bool),
- ('simulate', bool),
- ('input', Optional[str]),
- ('trace_duration', Optional[timedelta])])
-
-# This must be the only mutable global variable. All other global variables are constants to avoid magic literals.
-_debug = False # See -d/--debug flag.
-_DEBUG_FORCE = None # Ignore -d/--debug if this is not none.
-_PERFETTO_TRACE_DURATION_MS = 5000 # milliseconds
-_PERFETTO_TRACE_DURATION = timedelta(milliseconds=_PERFETTO_TRACE_DURATION_MS)
-
-# Type hinting names.
-T = TypeVar('T')
-NamedTupleMeta = Callable[
- ..., T] # approximation of a (S : NamedTuple<T> where S() == T) metatype.
-
-def parse_options(argv: List[str] = None):
- """Parse command line arguments and return an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Run one or more Android "
- "applications under various "
- "settings in order to measure "
- "startup time.")
- # argparse considers args starting with - and -- optional in --help, even though required=True.
- # by using a named argument group --help will clearly say that it's required instead of optional.
- required_named = parser.add_argument_group('required named arguments')
- required_named.add_argument('-p', '--package', action='append',
- dest='packages',
- help='package of the application', required=True)
- required_named.add_argument('-r', '--readahead', action='append',
- dest='readaheads',
- help='which readahead mode to use',
- choices=('warm', 'cold', 'mlock', 'fadvise'),
- required=True)
-
- # optional arguments
- # use a group here to get the required arguments to appear 'above' the optional arguments in help.
- optional_named = parser.add_argument_group('optional named arguments')
- optional_named.add_argument('-c', '--compiler-filter', action='append',
- dest='compiler_filters',
- help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter',
- choices=('speed', 'speed-profile', 'quicken'))
- optional_named.add_argument('-s', '--simulate', dest='simulate',
- action='store_true',
- help='Print which commands will run, but don\'t run the apps')
- optional_named.add_argument('-d', '--debug', dest='debug',
- action='store_true',
- help='Add extra debugging output')
- optional_named.add_argument('-o', '--output', dest='output', action='store',
- help='Write CSV output to file.')
- optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
- type=int, default=10,
- help='Timeout after this many seconds when executing a single run.')
- optional_named.add_argument('-lc', '--loop-count', dest='loop_count',
- default=1, type=int, action='store',
- help='How many times to loop a single run.')
- optional_named.add_argument('-in', '--inodes', dest='inodes', type=str,
- action='store',
- help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)')
- optional_named.add_argument('--compiler-trace-duration-ms',
- dest='trace_duration',
- type=lambda ms_str: timedelta(milliseconds=int(ms_str)),
- action='append',
- help='The trace duration (milliseconds) in '
- 'compilation')
- optional_named.add_argument('--compiler-type', dest='compiler_type',
- type=CompilerType, choices=list(CompilerType),
- default=CompilerType.DEVICE,
- help='The type of compiler.')
-
- return parser.parse_args(argv)
-
-def key_to_cmdline_flag(key: str) -> str:
- """Convert key into a command line flag, e.g. 'foo-bars' -> '--foo-bar' """
- if key.endswith("s"):
- key = key[:-1]
- return "--" + key.replace("_", "-")
-
-def as_run_command(tpl: NamedTuple) -> List[Union[str, Any]]:
- """
- Convert a named tuple into a command-line compatible arguments list.
-
- Example: ABC(1, 2, 3) -> ['--a', 1, '--b', 2, '--c', 3]
- """
- args = []
- for key, value in tpl._asdict().items():
- if value is None:
- continue
- args.append(key_to_cmdline_flag(key))
- args.append(value)
- return args
-
-def run_perfetto_collector(collector_info: CollectorPackageInfo,
- timeout: int,
- simulate: bool) -> Tuple[bool, TextIO]:
- """Run collector to collect prefetching trace.
-
- Returns:
- A tuple of whether the collection succeeds and the generated trace file.
- """
- tmp_output_file = tempfile.NamedTemporaryFile()
-
- collector = PerfettoTraceCollector(package=collector_info.package,
- activity=None,
- compiler_filter=collector_info.compiler_filter,
- timeout=timeout,
- simulate=simulate,
- trace_duration=_PERFETTO_TRACE_DURATION,
- save_destination_file_path=tmp_output_file.name)
- result = collector.run()
-
- return result is not None, tmp_output_file
-
-def parse_run_script_csv_file(csv_file: TextIO) -> DataFrame:
- """Parse a CSV file full of integers into a DataFrame."""
- csv_reader = csv.reader(csv_file)
-
- try:
- header_list = next(csv_reader)
- except StopIteration:
- header_list = []
-
- if not header_list:
- return None
-
- headers = [i for i in header_list]
-
- d = {}
- for row in csv_reader:
- header_idx = 0
-
- for i in row:
- v = i
- if i:
- v = int(i)
-
- header_key = headers[header_idx]
- l = d.get(header_key, [])
- l.append(v)
- d[header_key] = l
-
- header_idx = header_idx + 1
-
- return DataFrame(d)
-
-def build_ri_compiler_argv(inodes_path: str,
- perfetto_trace_file: str,
- trace_duration: Optional[timedelta]
- ) -> str:
- argv = ['-i', inodes_path, '--perfetto-trace',
- perfetto_trace_file]
-
- if trace_duration is not None:
- argv += ['--duration', str(int(trace_duration.total_seconds()
- * PerfettoTraceCollector.MS_PER_SEC))]
-
- print_utils.debug_print(argv)
- return argv
-
-def execute_run_using_perfetto_trace(collector_info,
- run_combos: Iterable[RunCommandArgs],
- simulate: bool,
- inodes_path: str,
- timeout: int,
- compiler_type: CompilerType,
- requires_trace_collection: bool) -> DataFrame:
- """ Executes run based on perfetto trace. """
- if requires_trace_collection:
- passed, perfetto_trace_file = run_perfetto_collector(collector_info,
- timeout,
- simulate)
- if not passed:
- raise RuntimeError('Cannot run perfetto collector!')
- else:
- perfetto_trace_file = tempfile.NamedTemporaryFile()
-
- with perfetto_trace_file:
- for combos in run_combos:
- if combos.readahead in _TRACING_READAHEADS:
- if simulate:
- compiler_trace_file = tempfile.NamedTemporaryFile()
- else:
- ri_compiler_argv = build_ri_compiler_argv(inodes_path,
- perfetto_trace_file.name,
- combos.trace_duration)
- compiler_trace_file = compiler.compile(compiler_type,
- inodes_path,
- ri_compiler_argv,
- combos.package,
- combos.activity)
-
- with compiler_trace_file:
- combos = combos._replace(input=compiler_trace_file.name)
- print_utils.debug_print(combos)
- output = PrefetchAppRunner(**combos._asdict()).run()
- else:
- print_utils.debug_print(combos)
- output = PrefetchAppRunner(**combos._asdict()).run()
-
- yield DataFrame(dict((x, [y]) for x, y in output)) if output else None
-
-def execute_run_combos(
- grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[RunCommandArgs]]],
- simulate: bool,
- inodes_path: str,
- timeout: int,
- compiler_type: CompilerType,
- requires_trace_collection: bool):
- # nothing will work if the screen isn't unlocked first.
- cmd_utils.execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT],
- timeout,
- simulate=simulate,
- shell=False)
-
- for collector_info, run_combos in grouped_run_combos:
- yield from execute_run_using_perfetto_trace(collector_info,
- run_combos,
- simulate,
- inodes_path,
- timeout,
- compiler_type,
- requires_trace_collection)
-
-def gather_results(commands: Iterable[Tuple[DataFrame]],
- key_list: List[str], value_list: List[Tuple[str, ...]]):
- print_utils.debug_print("gather_results: key_list = ", key_list)
- stringify_none = lambda s: s is None and "<none>" or s
- # yield key_list + ["time(ms)"]
- for (run_result_list, values) in itertools.zip_longest(commands, value_list):
- print_utils.debug_print("run_result_list = ", run_result_list)
- print_utils.debug_print("values = ", values)
-
- if not run_result_list:
- continue
-
- # RunCommandArgs(package='com.whatever', readahead='warm', compiler_filter=None)
- # -> {'package':['com.whatever'], 'readahead':['warm'], 'compiler_filter':[None]}
- values_dict = {}
- for k, v in values._asdict().items():
- if not k in key_list:
- continue
- values_dict[k] = [stringify_none(v)]
-
- values_df = DataFrame(values_dict)
- # project 'values_df' to be same number of rows as run_result_list.
- values_df = values_df.repeat(run_result_list.data_row_len)
-
- # the results are added as right-hand-side columns onto the existing labels for the table.
- values_df.merge_data_columns(run_result_list)
-
- yield values_df
-
-def eval_and_save_to_csv(output, annotated_result_values):
- printed_header = False
-
- csv_writer = csv.writer(output)
- for row in annotated_result_values:
- if not printed_header:
- headers = row.headers
- csv_writer.writerow(headers)
- printed_header = True
- # TODO: what about when headers change?
-
- for data_row in row.data_table:
- data_row = [d for d in data_row]
- csv_writer.writerow(data_row)
-
- output.flush() # see the output live.
-
-def coerce_to_list(opts: dict):
- """Tranform values of the dictionary to list.
- For example:
- 1 -> [1], None -> [None], [1,2,3] -> [1,2,3]
- [[1],[2]] -> [[1],[2]], {1:1, 2:2} -> [{1:1, 2:2}]
- """
- result = {}
- for key in opts:
- val = opts[key]
- result[key] = val if issubclass(type(val), list) else [val]
- return result
-
-def main():
- global _debug
-
- opts = parse_options()
- _debug = opts.debug
- if _DEBUG_FORCE is not None:
- _debug = _DEBUG_FORCE
-
- print_utils.DEBUG = _debug
- cmd_utils.SIMULATE = opts.simulate
-
- print_utils.debug_print("parsed options: ", opts)
-
- output_file = opts.output and open(opts.output, 'w') or sys.stdout
-
- combos = lambda: args_utils.generate_run_combinations(
- RunCommandArgs,
- coerce_to_list(vars(opts)),
- opts.loop_count)
- print_utils.debug_print_gen("run combinations: ", combos())
-
- grouped_combos = lambda: args_utils.generate_group_run_combinations(combos(),
- CollectorPackageInfo)
-
- print_utils.debug_print_gen("grouped run combinations: ", grouped_combos())
- requires_trace_collection = any(i in _TRACING_READAHEADS for i in opts.readaheads)
- exec = execute_run_combos(grouped_combos(),
- opts.simulate,
- opts.inodes,
- opts.timeout,
- opts.compiler_type,
- requires_trace_collection)
-
- results = gather_results(exec, _COMBINATORIAL_OPTIONS, combos())
-
- eval_and_save_to_csv(output_file, results)
-
- return 1
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner_test.py b/startop/scripts/app_startup/app_startup_runner_test.py
deleted file mode 100755
index 0c2bbea04f6a..000000000000
--- a/startop/scripts/app_startup/app_startup_runner_test.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for the app_startup_runner.py script.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> ./app_startup_runner_test.py
- $> pytest app_startup_runner_test.py
- $> python -m pytest app_startup_runner_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-import io
-import shlex
-import sys
-import typing
-# global imports
-from contextlib import contextmanager
-
-# local imports
-import app_startup_runner as asr
-# pip imports
-import pytest
-
-#
-# Argument Parsing Helpers
-#
-
-@contextmanager
-def ignore_stdout_stderr():
- """Ignore stdout/stderr output for duration of this context."""
- old_stdout = sys.stdout
- old_stderr = sys.stderr
- sys.stdout = io.StringIO()
- sys.stderr = io.StringIO()
- try:
- yield
- finally:
- sys.stdout = old_stdout
- sys.stderr = old_stderr
-
-@contextmanager
-def argparse_bad_argument(msg):
- """
- Assert that a SystemExit is raised when executing this context.
- If the assertion fails, print the message 'msg'.
- """
- with pytest.raises(SystemExit, message=msg):
- with ignore_stdout_stderr():
- yield
-
-def assert_bad_argument(args, msg):
- """
- Assert that the command line arguments in 'args' are malformed.
- Prints 'msg' if the assertion fails.
- """
- with argparse_bad_argument(msg):
- parse_args(args)
-
-def parse_args(args):
- """
- :param args: command-line like arguments as a single string
- :return: dictionary of parsed key/values
- """
- # "-a b -c d" => ['-a', 'b', '-c', 'd']
- return vars(asr.parse_options(shlex.split(args)))
-
-def default_dict_for_parsed_args(**kwargs):
- """
- # Combine it with all of the "optional" parameters' default values.
- """
- d = {'compiler_filters': None, 'simulate': False, 'debug': False,
- 'output': None, 'timeout': 10, 'loop_count': 1, 'inodes': None,
- 'trace_duration': None, 'compiler_type': asr.CompilerType.DEVICE}
- d.update(kwargs)
- return d
-
-def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
- """
- Combine default dict with all optional parameters with some mock required parameters.
- """
- d = {'packages': ['com.fake.package'], 'readaheads': ['warm']}
- if include_optional:
- d.update(default_dict_for_parsed_args())
- d.update(kwargs)
- return d
-
-def parse_optional_args(str):
- """
- Parse an argument string which already includes all the required arguments
- in default_mock_dict_for_parsed_args.
- """
- req = "--package com.fake.package --readahead warm"
- return parse_args("%s %s" % (req, str))
-
-def test_argparse():
- # missing arguments
- assert_bad_argument("", "-p and -r are required")
- assert_bad_argument("-r warm", "-p is required")
- assert_bad_argument("--readahead warm", "-p is required")
- assert_bad_argument("-p com.fake.package", "-r is required")
- assert_bad_argument("--package com.fake.package", "-r is required")
-
- # required arguments are parsed correctly
- ad = default_dict_for_parsed_args # assert dict
-
- assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'],
- readaheads=['warm'])
- assert parse_args("-p xyz -r warm") == ad(packages=['xyz'],
- readaheads=['warm'])
-
- assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'],
- readaheads=['warm'],
- simulate=True)
- assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'],
- readaheads=['warm'],
- simulate=True)
-
- # optional arguments are parsed correctly.
- mad = default_mock_dict_for_parsed_args # mock assert dict
- assert parse_optional_args("--output filename.csv") == mad(
- output='filename.csv')
- assert parse_optional_args("-o filename.csv") == mad(output='filename.csv')
-
- assert parse_optional_args("--timeout 123") == mad(timeout=123)
- assert parse_optional_args("-t 456") == mad(timeout=456)
-
- assert parse_optional_args("--loop-count 123") == mad(loop_count=123)
- assert parse_optional_args("-lc 456") == mad(loop_count=456)
-
- assert parse_optional_args("--inodes bar") == mad(inodes="bar")
- assert parse_optional_args("-in baz") == mad(inodes="baz")
-
-
-
-def test_key_to_cmdline_flag():
- assert asr.key_to_cmdline_flag("abc") == "--abc"
- assert asr.key_to_cmdline_flag("foos") == "--foo"
- assert asr.key_to_cmdline_flag("ba_r") == "--ba-r"
- assert asr.key_to_cmdline_flag("ba_zs") == "--ba-z"
-
-def test_parse_run_script_csv_file():
- # empty file -> empty list
- f = io.StringIO("")
- assert asr.parse_run_script_csv_file(f) == None
-
- # common case
- f = io.StringIO("TotalTime_ms,Displayed_ms\n1,2")
- df = asr.DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [2]})
-
- pf = asr.parse_run_script_csv_file(f)
- assert pf == df
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/app_startup/force_compiler_filter b/startop/scripts/app_startup/force_compiler_filter
deleted file mode 100755
index 08f983d92bea..000000000000
--- a/startop/scripts/app_startup/force_compiler_filter
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Forces an application APK to be compiled (by ART's dex2oat)
-# with a specific compiler filter.
-#
-# Example usage:
-# $> ./force_compiler_filter -p com.google.android.apps.maps -c speed-profile
-#
-# (The application may be started/stopped as a side effect)
-#
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-usage() {
- cat <<EOF
-Usage: $(basename $0) [OPTION]...
-
- Required:
- -p, --package package of the app to recompile
- -c, --compiler-filter override the compiler filter if set (default none)
- valid options are listed by: adb shell cmd package, under compile -m
-
- Optional:
- -a, --activity activity of the app to recompile
- -h, --help usage information (this)
- -v, --verbose enable extra verbose printing
- -w, --wait_time how long to wait for app startup (default 10) in seconds
-EOF
-}
-
-wait_time="10" # seconds
-
-parse_arguments() {
- while [[ $# -gt 0 ]]; do
- case "$1" in
- -a|--activity)
- activity="$2"
- shift
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -p|--package)
- package="$2"
- shift
- ;;
- -w|--wait_time)
- wait_time="$2"
- shift
- ;;
- -c|--compiler-filter)
- compiler_filter="$2"
- shift
- ;;
- -v|--verbose)
- verbose="y"
- ;;
- esac
- shift
- done
-
- if [[ -z "$compiler_filter" ]]; then
- echo "Missing required --compiler-filter" >&2
- echo ""
- usage
- exit 1
- fi
- if [[ -z "$package" ]]; then
- echo "Missing required --package" >&2
- echo ""
- usage
- exit 1
- fi
-
- if [[ "$activity" == "" ]]; then
- activity="$(get_activity_name "$package")"
- if [[ "$activity" == "" ]]; then
- echo "Activity name could not be found, invalid package name?" 1>&2
- exit 1
- else
- verbose_print "Activity name inferred: " "$activity"
- fi
- fi
-}
-
-force_package_compilation() {
- local arg_compiler_filter="$1"
- local arg_package="$2"
-
- if [[ $arg_compiler_filter == speed-profile ]]; then
- # Force the running app to dump its profiles to disk.
- remote_pkill "$arg_package" -SIGUSR1
- sleep 1 # give some time for above to complete.
- fi
-
- adb shell cmd package compile -m "$arg_compiler_filter" -f "$arg_package"
-}
-
-main() {
- parse_arguments "$@"
-
- if [[ $compiler_filter == speed-profile ]]; then
- # screen needs to be unlocked in order to run an app
- "$DIR"/unlock_screen
-
- local output=$("$DIR"/launch_application "$package" "$activity")
- if [[ $? -ne 0 ]]; then
- echo "launching application failed" >&2
- exit 1
- fi
-
- verbose_print "$output"
- # give some time for app startup to complete.
- # this is supposed to be an upper bound for measuring startup time.
- sleep "$wait_time"
- fi
-
- force_package_compilation "$compiler_filter" "$package"
-
- # kill the application to ensure next time it's started,
- # it picks up the correct compilation filter.
- adb shell am force-stop "$package"
- remote_pkill "$package"
-}
-
-main "$@"
diff --git a/startop/scripts/app_startup/launch_application b/startop/scripts/app_startup/launch_application
deleted file mode 100755
index 6704a5a97aa0..000000000000
--- a/startop/scripts/app_startup/launch_application
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-launch_application_usage() {
- cat <<EOF
-Usage: $(basename $0) <package> <activity>
-
- Positional Arguments:
- <package> package of the app to test
- <activity> activity to use
-
- Named Arguments:
- -h, --help usage information (this)
-EOF
-}
-
-launch_application() {
- local package="$1"
- local activity="$2"
-
- # if there's any $s inside of the activity name, it needs to be escaped to \$.
- # example '.app.honeycomb.Shell$HomeActivity'
- # if the $ is not escaped, adb shell will try to evaluate $HomeActivity to a variable.
- activity=${activity//\$/\\$}
-
- adb shell am start -S -W "$package"/"$activity"
-
- # pipe this into 'parse_metrics' to parse the output.
-}
-
-if [[ $# -lt 2 ]]; then
- launch_application_usage
- exit 1
-fi
-
-launch_application "$@"
diff --git a/startop/scripts/app_startup/lib/adb_utils.py b/startop/scripts/app_startup/lib/adb_utils.py
deleted file mode 100644
index 3cebc9a97a50..000000000000
--- a/startop/scripts/app_startup/lib/adb_utils.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Helper util libraries for calling adb command line."""
-
-import datetime
-import os
-import re
-import sys
-import time
-from typing import Optional
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
- os.path.abspath(__file__)))))
-import lib.cmd_utils as cmd_utils
-import lib.logcat_utils as logcat_utils
-
-
-def logcat_save_timestamp() -> str:
- """Gets the current logcat timestamp.
-
- Returns:
- A string of timestamp.
- """
- _, output = cmd_utils.run_adb_shell_command(
- "date -u +\'%Y-%m-%d %H:%M:%S.%N\'")
- return output
-
-def vm_drop_cache():
- """Free pagecache and slab object."""
- cmd_utils.run_adb_shell_command('echo 3 > /proc/sys/vm/drop_caches')
- # Sleep a little bit to provide enough time for cache cleanup.
- time.sleep(1)
-
-def root():
- """Roots adb and successive adb commands will run under root."""
- cmd_utils.run_shell_command('adb root')
-
-def disable_selinux():
- """Disables selinux setting."""
- _, output = cmd_utils.run_adb_shell_command('getenforce')
- if output == 'Permissive':
- return
-
- print('Disable selinux permissions and restart framework.')
- cmd_utils.run_adb_shell_command('setenforce 0')
- cmd_utils.run_adb_shell_command('stop')
- cmd_utils.run_adb_shell_command('start')
- cmd_utils.run_shell_command('adb wait-for-device')
-
-def pkill(procname: str):
- """Kills a process on device specified by the substring pattern in procname"""
- _, pids = cmd_utils.run_shell_command('adb shell ps | grep "{}" | '
- 'awk \'{{print $2;}}\''.
- format(procname))
-
- for pid in pids.split('\n'):
- pid = pid.strip()
- if pid:
- passed,_ = cmd_utils.run_adb_shell_command('kill {}'.format(pid))
- time.sleep(1)
-
-def parse_time_to_milliseconds(time: str) -> int:
- """Parses the time string to milliseconds."""
- # Example: +1s56ms, +56ms
- regex = r'\+((?P<second>\d+?)s)?(?P<millisecond>\d+?)ms'
- result = re.search(regex, time)
- second = 0
- if result.group('second'):
- second = int(result.group('second'))
- ms = int(result.group('millisecond'))
- return second * 1000 + ms
-
-def blocking_wait_for_logcat_displayed_time(timestamp: datetime.datetime,
- package: str,
- timeout: int) -> Optional[int]:
- """Parses the displayed time in the logcat.
-
- Returns:
- the displayed time.
- """
- pattern = re.compile('.*ActivityTaskManager: Displayed {}.*'.format(package))
- # 2019-07-02 22:28:34.469453349 -> 2019-07-02 22:28:34.469453
- timestamp = datetime.datetime.strptime(timestamp[:-3],
- '%Y-%m-%d %H:%M:%S.%f')
- timeout_dt = timestamp + datetime.timedelta(0, timeout)
- # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager:
- # Displayed com.android.settings/.Settings: +927ms
- result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
- pattern,
- timeout_dt)
- if not result or not '+' in result:
- return None
- displayed_time = result[result.rfind('+'):]
-
- return parse_time_to_milliseconds(displayed_time)
-
-def delete_file_on_device(file_path: str) -> None:
- """ Deletes a file on the device. """
- cmd_utils.run_adb_shell_command(
- "[[ -f '{file_path}' ]] && rm -f '{file_path}' || "
- "exit 0".format(file_path=file_path))
-
-def set_prop(property: str, value: str) -> None:
- """ Sets property using adb shell. """
- cmd_utils.run_adb_shell_command('setprop "{property}" "{value}"'.format(
- property=property, value=value))
-
-def pull_file(device_file_path: str, output_file_path: str) -> None:
- """ Pulls file from device to output """
- cmd_utils.run_shell_command('adb pull "{device_file_path}" "{output_file_path}"'.
- format(device_file_path=device_file_path,
- output_file_path=output_file_path))
diff --git a/startop/scripts/app_startup/lib/adb_utils_test.py b/startop/scripts/app_startup/lib/adb_utils_test.py
deleted file mode 100644
index e590fed568e3..000000000000
--- a/startop/scripts/app_startup/lib/adb_utils_test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import adb_utils
-
-# pip imports
-import pytest
-
-def test_parse_time_to_milliseconds():
- # Act
- result1 = adb_utils.parse_time_to_milliseconds('+1s7ms')
- result2 = adb_utils.parse_time_to_milliseconds('+523ms')
-
- # Assert
- assert result1 == 1007
- assert result2 == 523
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/app_startup/lib/app_runner.py b/startop/scripts/app_startup/lib/app_runner.py
deleted file mode 100644
index 78873fa51ab5..000000000000
--- a/startop/scripts/app_startup/lib/app_runner.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# Copyright 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.
-
-"""Class to run an app."""
-import os
-import sys
-from typing import Optional, List, Tuple
-
-# local import
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
- os.path.abspath(__file__)))))
-
-import app_startup.lib.adb_utils as adb_utils
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-
-class AppRunnerListener(object):
- """Interface for lisenter of AppRunner. """
-
- def preprocess(self) -> None:
- """Preprocess callback to initialized before the app is running. """
- pass
-
- def postprocess(self, pre_launch_timestamp: str) -> None:
- """Postprocess callback to cleanup after the app is running.
-
- param:
- 'pre_launch_timestamp': indicates the timestamp when the app is
- launching.. """
- pass
-
- def metrics_selector(self, am_start_output: str,
- pre_launch_timestamp: str) -> None:
- """A metrics selection callback that waits for the desired metrics to
- show up in logcat.
- params:
- 'am_start_output': indicates the output of app startup.
- 'pre_launch_timestamp': indicates the timestamp when the app is
- launching.
- returns:
- a string in the format of "<metric>=<value>\n<metric>=<value>\n..."
- for further parsing. For example "TotalTime=123\nDisplayedTime=121".
- Return an empty string if no metrics need to be parsed further.
- """
- pass
-
-class AppRunner(object):
- """ Class to run an app. """
- # static variables
- DIR = os.path.abspath(os.path.dirname(__file__))
- APP_STARTUP_DIR = os.path.dirname(DIR)
- IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(DIR,
- '../../iorap/common'))
- DEFAULT_TIMEOUT = 30 # seconds
-
- def __init__(self,
- package: str,
- activity: Optional[str],
- compiler_filter: Optional[str],
- timeout: Optional[int],
- simulate: bool):
- self.package = package
- self.simulate = simulate
-
- # If the argument activity is None, try to set it.
- self.activity = activity
- if self.simulate:
- self.activity = 'act'
- if self.activity is None:
- self.activity = AppRunner.get_activity(self.package)
-
- self.compiler_filter = compiler_filter
- self.timeout = timeout if timeout else AppRunner.DEFAULT_TIMEOUT
-
- self.listeners = []
-
- def add_callbacks(self, listener: AppRunnerListener):
- self.listeners.append(listener)
-
- def remove_callbacks(self, listener: AppRunnerListener):
- self.listeners.remove(listener)
-
- @staticmethod
- def get_activity(package: str) -> str:
- """ Tries to set the activity based on the package. """
- passed, activity = cmd_utils.run_shell_func(
- AppRunner.IORAP_COMMON_BASH_SCRIPT,
- 'get_activity_name',
- [package])
-
- if not passed or not activity:
- raise ValueError(
- 'Activity name could not be found, invalid package name?!')
-
- return activity
-
- def configure_compiler_filter(self) -> bool:
- """Configures compiler filter (e.g. speed).
-
- Returns:
- A bool indicates whether configure of compiler filer succeeds or not.
- """
- if not self.compiler_filter:
- print_utils.debug_print('No --compiler-filter specified, don\'t'
- ' need to force it.')
- return True
-
- passed, current_compiler_filter_info = \
- cmd_utils.run_shell_command(
- '{} --package {}'.format(os.path.join(AppRunner.APP_STARTUP_DIR,
- 'query_compiler_filter.py'),
- self.package))
-
- if passed != 0:
- return passed
-
- # TODO: call query_compiler_filter directly as a python function instead of
- # these shell calls.
- current_compiler_filter, current_reason, current_isa = \
- current_compiler_filter_info.split(' ')
- print_utils.debug_print('Compiler Filter={} Reason={} Isa={}'.format(
- current_compiler_filter, current_reason, current_isa))
-
- # Don't trust reasons that aren't 'unknown' because that means
- # we didn't manually force the compilation filter.
- # (e.g. if any automatic system-triggered compilations are not unknown).
- if current_reason != 'unknown' or \
- current_compiler_filter != self.compiler_filter:
- passed, _ = adb_utils.run_shell_command('{}/force_compiler_filter '
- '--compiler-filter "{}" '
- '--package "{}"'
- ' --activity "{}'.
- format(AppRunner.APP_STARTUP_DIR,
- self.compiler_filter,
- self.package,
- self.activity))
- else:
- adb_utils.debug_print('Queried compiler-filter matched requested '
- 'compiler-filter, skip forcing.')
- passed = False
- return passed
-
- def run(self) -> Optional[List[Tuple[str]]]:
- """Runs an app.
-
- Returns:
- A list of (metric, value) tuples.
- """
- print_utils.debug_print('==========================================')
- print_utils.debug_print('===== START =====')
- print_utils.debug_print('==========================================')
- # Run the preprocess.
- for listener in self.listeners:
- listener.preprocess()
-
- # Ensure the APK is currently compiled with whatever we passed in
- # via --compiler-filter.
- # No-op if this option was not passed in.
- if not self.configure_compiler_filter():
- print_utils.error_print('Compiler filter configuration failed!')
- return None
-
- pre_launch_timestamp = adb_utils.logcat_save_timestamp()
- # Launch the app.
- results = self.launch_app(pre_launch_timestamp)
-
- # Run the postprocess.
- for listener in self.listeners:
- listener.postprocess(pre_launch_timestamp)
-
- return results
-
- def launch_app(self, pre_launch_timestamp: str) -> Optional[List[Tuple[str]]]:
- """ Launches the app.
-
- Returns:
- A list of (metric, value) tuples.
- """
- print_utils.debug_print('Running with timeout {}'.format(self.timeout))
-
- passed, am_start_output = cmd_utils.run_shell_command('timeout {timeout} '
- '"{DIR}/launch_application" '
- '"{package}" '
- '"{activity}"'.
- format(timeout=self.timeout,
- DIR=AppRunner.APP_STARTUP_DIR,
- package=self.package,
- activity=self.activity))
- if not passed and not self.simulate:
- return None
-
- return self.wait_for_app_finish(pre_launch_timestamp, am_start_output)
-
- def wait_for_app_finish(self,
- pre_launch_timestamp: str,
- am_start_output: str) -> Optional[List[Tuple[str]]]:
- """ Wait for app finish and all metrics are shown in logcat.
-
- Returns:
- A list of (metric, value) tuples.
- """
- if self.simulate:
- return [('TotalTime', '123')]
-
- ret = []
- for listener in self.listeners:
- output = listener.metrics_selector(am_start_output,
- pre_launch_timestamp)
- ret = ret + AppRunner.parse_metrics_output(output)
-
- return ret
-
- @staticmethod
- def parse_metrics_output(input: str) -> List[
- Tuple[str, str, str]]:
- """Parses output of app startup to metrics and corresponding values.
-
- It converts 'a=b\nc=d\ne=f\n...' into '[(a,b,''),(c,d,''),(e,f,'')]'
-
- Returns:
- A list of tuples that including metric name, metric value and rest info.
- """
- all_metrics = []
- for line in input.split('\n'):
- if not line:
- continue
- splits = line.split('=')
- if len(splits) < 2:
- print_utils.error_print('Bad line "{}"'.format(line))
- continue
- metric_name = splits[0]
- metric_value = splits[1]
- rest = splits[2] if len(splits) > 2 else ''
- if rest:
- print_utils.error_print('Corrupt line "{}"'.format(line))
- print_utils.debug_print('metric: "{metric_name}", '
- 'value: "{metric_value}" '.
- format(metric_name=metric_name,
- metric_value=metric_value))
-
- all_metrics.append((metric_name, metric_value))
- return all_metrics
-
- @staticmethod
- def parse_total_time( am_start_output: str) -> Optional[str]:
- """Parses the total time from 'adb shell am start pkg' output.
-
- Returns:
- the total time of app startup.
- """
- for line in am_start_output.split('\n'):
- if 'TotalTime:' in line:
- return line[len('TotalTime:'):].strip()
- return None
-
diff --git a/startop/scripts/app_startup/lib/app_runner_test.py b/startop/scripts/app_startup/lib/app_runner_test.py
deleted file mode 100644
index 33d233b03aab..000000000000
--- a/startop/scripts/app_startup/lib/app_runner_test.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 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.
-#
-
-"""Unit tests for the AppRunner."""
-import os
-import sys
-from pathlib import Path
-
-from app_runner import AppRunner, AppRunnerListener
-from mock import Mock, call, patch
-
-# The path is "frameworks/base/startop/scripts/"
-sys.path.append(Path(os.path.realpath(__file__)).parents[2])
-import lib.cmd_utils as cmd_utils
-
-class AppRunnerTestListener(AppRunnerListener):
- def preprocess(self) -> None:
- cmd_utils.run_shell_command('pre'),
-
- def postprocess(self, pre_launch_timestamp: str) -> None:
- cmd_utils.run_shell_command('post'),
-
- def metrics_selector(self, am_start_output: str,
- pre_launch_timestamp: str) -> None:
- return 'TotalTime=123\n'
-
-RUNNER = AppRunner(package='music',
- activity='MainActivity',
- compiler_filter='speed',
- timeout=None,
- simulate=False)
-
-
-
-def test_configure_compiler_filter():
- with patch('lib.cmd_utils.run_shell_command',
- new_callable=Mock) as mock_run_shell_command:
- mock_run_shell_command.return_value = (True, 'speed arm64 kUpToDate')
-
- RUNNER.configure_compiler_filter()
-
- calls = [call(os.path.realpath(
- os.path.join(RUNNER.DIR,
- '../query_compiler_filter.py')) + ' --package music')]
- mock_run_shell_command.assert_has_calls(calls)
-
-def test_parse_metrics_output():
- input = 'a1=b1\nc1=d1\ne1=f1'
- ret = RUNNER.parse_metrics_output(input)
-
- assert ret == [('a1', 'b1'), ('c1', 'd1'), ('e1', 'f1')]
-
-def _mocked_run_shell_command(*args, **kwargs):
- if args[0] == 'adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"':
- return (True, "2019-07-02 23:20:06.972674825")
- elif args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
- return (True, '9999')
- else:
- return (True, 'a1=b1\nc1=d1=d2\ne1=f1')
-
-@patch('app_startup.lib.adb_utils.blocking_wait_for_logcat_displayed_time')
-@patch('lib.cmd_utils.run_shell_command')
-def test_run(mock_run_shell_command,
- mock_blocking_wait_for_logcat_displayed_time):
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- mock_blocking_wait_for_logcat_displayed_time.return_value = 123
-
- test_listener = AppRunnerTestListener()
- RUNNER.add_callbacks(test_listener)
-
- result = RUNNER.run()
-
- RUNNER.remove_callbacks(test_listener)
-
- calls = [call('pre'),
- call(os.path.realpath(
- os.path.join(RUNNER.DIR,
- '../query_compiler_filter.py')) +
- ' --package music'),
- call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'),
- call(
- 'timeout {timeout} "{DIR}/launch_application" "{package}" "{activity}"'
- .format(timeout=30,
- DIR=os.path.realpath(os.path.dirname(RUNNER.DIR)),
- package='music',
- activity='MainActivity',
- timestamp='2019-07-02 23:20:06.972674825')),
- call('post')
- ]
- mock_run_shell_command.assert_has_calls(calls)
- assert result == [('TotalTime', '123')]
- assert len(RUNNER.listeners) == 0 \ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/args_utils.py b/startop/scripts/app_startup/lib/args_utils.py
deleted file mode 100644
index 080f3b53157b..000000000000
--- a/startop/scripts/app_startup/lib/args_utils.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import itertools
-import os
-import sys
-from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, \
- TypeVar, Optional
-
-# local import
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
- os.path.abspath(__file__)))))
-import lib.print_utils as print_utils
-
-T = TypeVar('T')
-NamedTupleMeta = Callable[
- ..., T] # approximation of a (S : NamedTuple<T> where S() == T) metatype.
-FilterFuncType = Callable[[NamedTuple], bool]
-
-def dict_lookup_any_key(dictionary: dict, *keys: List[Any]):
- for k in keys:
- if k in dictionary:
- return dictionary[k]
-
-
- print_utils.debug_print("None of the keys {} were in the dictionary".format(
- keys))
- return [None]
-
-def generate_run_combinations(named_tuple: NamedTupleMeta[T],
- opts_dict: Dict[str, List[Optional[object]]],
- loop_count: int = 1) -> Iterable[T]:
- """
- Create all possible combinations given the values in opts_dict[named_tuple._fields].
-
- :type T: type annotation for the named_tuple type.
- :param named_tuple: named tuple type, whose fields are used to make combinations for
- :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields.
- :param loop_count: number of repetitions.
- :return: an iterable over named_tuple instances.
- """
- combinations_list = []
- for k in named_tuple._fields:
- # the key can be either singular or plural , e.g. 'package' or 'packages'
- val = dict_lookup_any_key(opts_dict, k, k + "s")
-
- # treat {'x': None} key value pairs as if it was [None]
- # otherwise itertools.product throws an exception about not being able to iterate None.
- combinations_list.append(val or [None])
-
- print_utils.debug_print("opts_dict: ", opts_dict)
- print_utils.debug_print_nd("named_tuple: ", named_tuple)
- print_utils.debug_print("combinations_list: ", combinations_list)
-
- for i in range(loop_count):
- for combo in itertools.product(*combinations_list):
- yield named_tuple(*combo)
-
-def filter_run_combinations(named_tuple: NamedTuple,
- filters: List[FilterFuncType]) -> bool:
- for filter in filters:
- if filter(named_tuple):
- return False
- return True
-
-def generate_group_run_combinations(run_combinations: Iterable[NamedTuple],
- dst_nt: NamedTupleMeta[T]) \
- -> Iterable[Tuple[T, Iterable[NamedTuple]]]:
- def group_by_keys(src_nt):
- src_d = src_nt._asdict()
- # now remove the keys that aren't legal in dst.
- for illegal_key in set(src_d.keys()) - set(dst_nt._fields):
- if illegal_key in src_d:
- del src_d[illegal_key]
-
- return dst_nt(**src_d)
-
- for args_list_it in itertools.groupby(run_combinations, group_by_keys):
- (group_key_value, args_it) = args_list_it
- yield (group_key_value, args_it)
diff --git a/startop/scripts/app_startup/lib/args_utils_test.py b/startop/scripts/app_startup/lib/args_utils_test.py
deleted file mode 100644
index 4b7e0fa20627..000000000000
--- a/startop/scripts/app_startup/lib/args_utils_test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the args_utils.py script."""
-
-import typing
-
-import args_utils
-
-def generate_run_combinations(*args):
- # expand out the generator values so that assert x == y works properly.
- return [i for i in args_utils.generate_run_combinations(*args)]
-
-def test_generate_run_combinations():
- blank_nd = typing.NamedTuple('Blank')
- assert generate_run_combinations(blank_nd, {}, 1) == [()], "empty"
- assert generate_run_combinations(blank_nd, {'a': ['a1', 'a2']}) == [
- ()], "empty filter"
- a_nd = typing.NamedTuple('A', [('a', str)])
- assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None"
- assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), (
- 'a2',)], "one item"
- assert generate_run_combinations(a_nd,
- {'a': ['a1', 'a2'], 'b': ['b1', 'b2']}) == [
- ('a1',), ('a2',)], \
- "one item filter"
- assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}, 2) == [('a1',), (
- 'a2',), ('a1',), ('a2',)], "one item"
- ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)])
- assert generate_run_combinations(ab_nd,
- {'a': ['a1', 'a2'],
- 'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
- ab_nd('a1', 'b2'),
- ab_nd('a2', 'b1'),
- ab_nd('a2', 'b2')], \
- "two items"
-
- assert generate_run_combinations(ab_nd,
- {'as': ['a1', 'a2'],
- 'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
- ab_nd('a1', 'b2'),
- ab_nd('a2', 'b1'),
- ab_nd('a2', 'b2')], \
- "two items plural"
diff --git a/startop/scripts/app_startup/lib/common b/startop/scripts/app_startup/lib/common
deleted file mode 100755
index bedaa1e10288..000000000000
--- a/startop/scripts/app_startup/lib/common
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/bash
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-if [[ -z $ANDROID_BUILD_TOP ]]; then
- echo "Please run source build/envsetup.sh first" >&2
- exit 1
-fi
-
-source $ANDROID_BUILD_TOP/build/envsetup.sh
-
-verbose_print() {
- if [[ "$verbose" == "y" ]]; then
- echo "$@" >&2
- fi
-}
-
-remote_pidof() {
- local procname="$1"
- adb shell ps | grep "$procname" | awk '{print $2;}'
-}
-
-remote_pkill() {
- local procname="$1"
- shift
-
- local the_pids=$(remote_pidof "$procname")
- local pid
-
- for pid in $the_pids; do
- verbose_print adb shell kill "$@" "$pid"
- adb shell kill "$@" "$pid"
- done
-}
-
-get_activity_name() {
- local package="$1"
- local action_key="android.intent.action.MAIN:"
-
- # Example query-activities output being parsed:
- #
- # Activity #14:
- # priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true
- # com.google.android.videos/com.google.android.youtube.videos.EntryPoint
- # Activity #15:
- # priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true
- # com.google.android.youtube/.app.honeycomb.Shell$HomeActivity
-
- # Given package 'com.google.android.youtube' return '.app.honeycomb.Shell$HomeActivity'
-
- local activity_line="$(adb shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER | grep "$package/")"
- IFS="/" read -a array <<< "$activity_line"
- local activity_name="${array[1]}"
-
- # Activities starting with '.' are shorthand for having their package name prefixed.
- if [[ $activity_name == .* ]]; then
- activity_name="${package}${activity_name}"
- fi
- echo "$activity_name"
-}
-
-# Use with logcat_from_timestamp to skip all past log-lines.
-logcat_save_timestamp() {
- adb shell 'date -u +"%Y-%m-%d %H:%M:%S.%N"'
-}
-
-# Roll forward logcat to only show events
-# since the specified timestamp.
-#
-# i.e. don't look at historical logcat,
-# only look at FUTURE logcat.
-#
-# First use 'logcat_save_timestamp'
-# Then do whatever action you want.
-# Then use 'logcat_from_timestamp_bg $timestamp'
-logcat_from_timestamp_bg() {
- local timestamp="$1"
- shift # drop timestamp from args.
- verbose_print adb logcat -T \"$timestamp\" \"$@\"
- adb logcat -v UTC -T "$timestamp" "$@" &
- logcat_from_timestamp_pid=$!
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-# If successful, also echo the line that matched the pattern.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_select_pattern() {
- local timeout="$1"
- local timestamp="$2"
- local pattern="$3"
-
- local logcat_fd
-
- coproc logcat_fd {
- kill_children_quietly() {
- kill "$logcat_pidd"
- wait "$logcat_pidd" 2>/dev/null
- }
-
- trap 'kill_children_quietly' EXIT # kill logcat when this coproc is killed.
-
- # run logcat in the background so it can be killed.
- logcat_from_timestamp_bg "$timestamp"
- logcat_pidd=$logcat_from_timestamp_pid
- wait "$logcat_pidd"
- }
- local logcat_pid="$!"
- verbose_print "[LOGCAT] Spawn pid $logcat_pid"
-
- local timeout_ts="$(date -d "now + ${timeout} seconds" '+%s')"
- local now_ts="0"
-
- local return_code=1
-
- verbose_print "logcat_wait_for_pattern begin"
-
- while read -t "$timeout" -r -u "${logcat_fd[0]}" logcat_output; do
- if (( $VERBOSE_LOGCAT )); then
- verbose_print "LOGCAT: $logcat_output"
- fi
- if [[ "$logcat_output:" == *"$pattern"* ]]; then
- verbose_print "LOGCAT: " "$logcat_output"
- verbose_print "WE DID SEE PATTERN" '<<' "$pattern" '>>.'
- echo "$logcat_output"
- return_code=0
- break
- fi
- now_ts="$(date -d "now" '+%s')"
- if (( now_ts >= timeout_ts )); then
- verbose_print "DID TIMEOUT BEFORE SEEING ANYTHING (timeout=$timeout seconds) " '<<' "$pattern" '>>.'
- break
- fi
- done
-
- # Don't leave logcat lying around since it will keep going.
- kill "$logcat_pid"
- # Suppress annoying 'Terminated...' message.
- wait "$logcat_pid" 2>/dev/null
-
- verbose_print "[LOGCAT] $logcat_pid should be killed"
-
- return $return_code
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_wait_for_pattern() {
- logcat_select_pattern "$@" > /dev/null
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-# If successful, extract with the regular expression pattern in #4
-# and return the first capture group.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_extract_pattern() {
- local timeout="$1"
- local timestamp="$2"
- local pattern="$3"
- local re_pattern="$4"
-
- local result
- local exit_code
-
- result="$(logcat_select_pattern "$@")"
- exit_code=$?
-
- if [[ $exit_code -ne 0 ]]; then
- return $exit_code
- fi
-
- echo "$result" | sed 's/'"$re_pattern"'/\1/g'
-}
-
-# Join array
-# FOO=(a b c)
-# join_by , "${FOO[@]}" #a,b,c
-join_by() {
- local IFS="$1"
- shift
- echo "$*"
-}
diff --git a/startop/scripts/app_startup/lib/data_frame.py b/startop/scripts/app_startup/lib/data_frame.py
deleted file mode 100644
index 20a2308637f2..000000000000
--- a/startop/scripts/app_startup/lib/data_frame.py
+++ /dev/null
@@ -1,201 +0,0 @@
-import itertools
-from typing import Dict, List
-
-class DataFrame:
- """Table-like class for storing a 2D cells table with named columns."""
- def __init__(self, data: Dict[str, List[object]] = {}):
- """
- Create a new DataFrame from a dictionary (keys = headers,
- values = columns).
- """
- self._headers = [i for i in data.keys()]
- self._rows = []
-
- row_num = 0
-
- def get_data_row(idx):
- r = {}
- for header, header_data in data.items():
-
- if not len(header_data) > idx:
- continue
-
- r[header] = header_data[idx]
-
- return r
-
- while True:
- row_dict = get_data_row(row_num)
- if len(row_dict) == 0:
- break
-
- self._append_row(row_dict.keys(), row_dict.values())
- row_num = row_num + 1
-
- def concat_rows(self, other: 'DataFrame') -> None:
- """
- In-place concatenate rows of other into the rows of the
- current DataFrame.
-
- None is added in pre-existing cells if new headers
- are introduced.
- """
- other_datas = other._data_only()
-
- other_headers = other.headers
-
- for d in other_datas:
- self._append_row(other_headers, d)
-
- def _append_row(self, headers: List[str], data: List[object]):
- new_row = {k:v for k,v in zip(headers, data)}
- self._rows.append(new_row)
-
- for header in headers:
- if not header in self._headers:
- self._headers.append(header)
-
- def __repr__(self):
-# return repr(self._rows)
- repr = ""
-
- header_list = self._headers_only()
-
- row_format = u""
- for header in header_list:
- row_format = row_format + u"{:>%d}" %(len(header) + 1)
-
- repr = row_format.format(*header_list) + "\n"
-
- for v in self._data_only():
- repr = repr + row_format.format(*v) + "\n"
-
- return repr
-
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- return self.headers == other.headers and self.data_table == other.data_table
- else:
- print("wrong instance", other.__class__)
- return False
-
- @property
- def headers(self) -> List[str]:
- return [i for i in self._headers_only()]
-
- @property
- def data_table(self) -> List[List[object]]:
- return list(self._data_only())
-
- @property
- def data_table_transposed(self) -> List[List[object]]:
- return list(self._transposed_data())
-
- @property
- def data_row_len(self) -> int:
- return len(self._rows)
-
- def data_row_at(self, idx) -> List[object]:
- """
- Return a single data row at the specified index (0th based).
-
- Accepts negative indices, e.g. -1 is last row.
- """
- row_dict = self._rows[idx]
- l = []
-
- for h in self._headers_only():
- l.append(row_dict.get(h)) # Adds None in blank spots.
-
- return l
-
- def copy(self) -> 'DataFrame':
- """
- Shallow copy of this DataFrame.
- """
- return self.repeat(count=0)
-
- def repeat(self, count: int) -> 'DataFrame':
- """
- Returns a new DataFrame where each row of this dataframe is repeated count times.
- A repeat of a row is adjacent to other repeats of that same row.
- """
- df = DataFrame()
- df._headers = self._headers.copy()
-
- rows = []
- for row in self._rows:
- for i in range(count):
- rows.append(row.copy())
-
- df._rows = rows
-
- return df
-
- def merge_data_columns(self, other: 'DataFrame'):
- """
- Merge self and another DataFrame by adding the data from other column-wise.
- For any headers that are the same, data from 'other' is preferred.
- """
- for h in other._headers:
- if not h in self._headers:
- self._headers.append(h)
-
- append_rows = []
-
- for self_dict, other_dict in itertools.zip_longest(self._rows, other._rows):
- if not self_dict:
- d = {}
- append_rows.append(d)
- else:
- d = self_dict
-
- d_other = other_dict
- if d_other:
- for k,v in d_other.items():
- d[k] = v
-
- for r in append_rows:
- self._rows.append(r)
-
- def data_row_reduce(self, fnc) -> 'DataFrame':
- """
- Reduces the data row-wise by applying the fnc to each row (column-wise).
- Empty cells are skipped.
-
- fnc(Iterable[object]) -> object
- fnc is applied over every non-empty cell in that column (descending row-wise).
-
- Example:
- DataFrame({'a':[1,2,3]}).data_row_reduce(sum) == DataFrame({'a':[6]})
-
- Returns a new single-row DataFrame.
- """
- df = DataFrame()
- df._headers = self._headers.copy()
-
- def yield_by_column(header_key):
- for row_dict in self._rows:
- val = row_dict.get(header_key)
- if val:
- yield val
-
- new_row_dict = {}
- for h in df._headers:
- cell_value = fnc(yield_by_column(h))
- new_row_dict[h] = cell_value
-
- df._rows = [new_row_dict]
- return df
-
- def _headers_only(self):
- return self._headers
-
- def _data_only(self):
- row_len = len(self._rows)
-
- for i in range(row_len):
- yield self.data_row_at(i)
-
- def _transposed_data(self):
- return zip(*self._data_only()) \ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/data_frame_test.py b/startop/scripts/app_startup/lib/data_frame_test.py
deleted file mode 100644
index 1cbc1cbe45cb..000000000000
--- a/startop/scripts/app_startup/lib/data_frame_test.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the data_frame.py script."""
-
-from data_frame import DataFrame
-
-def test_data_frame():
- # trivial empty data frame
- df = DataFrame()
- assert df.headers == []
- assert df.data_table == []
- assert df.data_table_transposed == []
-
- # common case, same number of values in each place.
- df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
- assert df.headers == ['TotalTime_ms', 'Displayed_ms']
- assert df.data_table == [[1, 4], [2, 5], [3, 6]]
- assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
-
- # varying num values.
- df = DataFrame({'many': [1, 2], 'none': []})
- assert df.headers == ['many', 'none']
- assert df.data_table == [[1, None], [2, None]]
- assert df.data_table_transposed == [(1, 2), (None, None)]
-
- df = DataFrame({'many': [], 'none': [1, 2]})
- assert df.headers == ['many', 'none']
- assert df.data_table == [[None, 1], [None, 2]]
- assert df.data_table_transposed == [(None, None), (1, 2)]
-
- # merge multiple data frames
- df = DataFrame()
- df.concat_rows(DataFrame())
- assert df.headers == []
- assert df.data_table == []
- assert df.data_table_transposed == []
-
- df = DataFrame()
- df2 = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
-
- df.concat_rows(df2)
- assert df.headers == ['TotalTime_ms', 'Displayed_ms']
- assert df.data_table == [[1, 4], [2, 5], [3, 6]]
- assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
-
- df = DataFrame({'TotalTime_ms': [1, 2]})
- df2 = DataFrame({'Displayed_ms': [4, 5]})
-
- df.concat_rows(df2)
- assert df.headers == ['TotalTime_ms', 'Displayed_ms']
- assert df.data_table == [[1, None], [2, None], [None, 4], [None, 5]]
-
- df = DataFrame({'TotalTime_ms': [1, 2]})
- df2 = DataFrame({'TotalTime_ms': [3, 4], 'Displayed_ms': [5, 6]})
-
- df.concat_rows(df2)
- assert df.headers == ['TotalTime_ms', 'Displayed_ms']
- assert df.data_table == [[1, None], [2, None], [3, 5], [4, 6]]
-
- # data_row_at
- df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
- assert df.data_row_at(-1) == [3, 6]
- assert df.data_row_at(2) == [3, 6]
- assert df.data_row_at(1) == [2, 5]
-
- # repeat
- df = DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [4]})
- df2 = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
- assert df.repeat(3) == df2
-
- # repeat
- df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
- assert df.data_row_len == 3
- df = DataFrame({'TotalTime_ms': [1, 1]})
- assert df.data_row_len == 2
-
- # repeat
- df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
- assert df.data_row_len == 3
- df = DataFrame({'TotalTime_ms': [1, 1]})
- assert df.data_row_len == 2
-
- # data_row_reduce
- df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
- df_sum = DataFrame({'TotalTime_ms': [3], 'Displayed_ms': [12]})
- assert df.data_row_reduce(sum) == df_sum
-
- # merge_data_columns
- df = DataFrame({'TotalTime_ms': [1, 2, 3]})
- df2 = DataFrame({'Displayed_ms': [3, 4, 5, 6]})
-
- df.merge_data_columns(df2)
- assert df == DataFrame(
- {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4, 5, 6]})
-
- df = DataFrame({'TotalTime_ms': [1, 2, 3]})
- df2 = DataFrame({'Displayed_ms': [3, 4]})
-
- df.merge_data_columns(df2)
- assert df == DataFrame(
- {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4]})
-
- df = DataFrame({'TotalTime_ms': [1, 2, 3]})
- df2 = DataFrame({'TotalTime_ms': [10, 11]})
-
- df.merge_data_columns(df2)
- assert df == DataFrame({'TotalTime_ms': [10, 11, 3]})
-
- df = DataFrame({'TotalTime_ms': []})
- df2 = DataFrame({'TotalTime_ms': [10, 11]})
-
- df.merge_data_columns(df2)
- assert df == DataFrame({'TotalTime_ms': [10, 11]})
diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector.py b/startop/scripts/app_startup/lib/perfetto_trace_collector.py
deleted file mode 100644
index 9ffb3494da49..000000000000
--- a/startop/scripts/app_startup/lib/perfetto_trace_collector.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright 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.
-
-"""Class to collector perfetto trace."""
-import datetime
-import os
-import re
-import sys
-import time
-from datetime import timedelta
-from typing import Optional, List, Tuple
-
-# global variables
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(os.path.dirname(DIR)))
-
-import app_startup.lib.adb_utils as adb_utils
-from app_startup.lib.app_runner import AppRunner, AppRunnerListener
-import lib.print_utils as print_utils
-import lib.logcat_utils as logcat_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-
-class PerfettoTraceCollector(AppRunnerListener):
- """ Class to collect perfetto trace.
-
- To set trace duration of perfetto, change the 'trace_duration_ms'.
- To pull the generated perfetto trace on device, set the 'output'.
- """
- TRACE_FILE_SUFFIX = 'perfetto_trace.pb'
- TRACE_DURATION_PROP = 'iorapd.perfetto.trace_duration_ms'
- MS_PER_SEC = 1000
- DEFAULT_TRACE_DURATION = timedelta(milliseconds=5000) # 5 seconds
- _COLLECTOR_TIMEOUT_MULTIPLIER = 10 # take the regular timeout and multiply
-
- def __init__(self,
- package: str,
- activity: Optional[str],
- compiler_filter: Optional[str],
- timeout: Optional[int],
- simulate: bool,
- trace_duration: timedelta = DEFAULT_TRACE_DURATION,
- save_destination_file_path: Optional[str] = None):
- """ Initialize the perfetto trace collector. """
- self.app_runner = AppRunner(package,
- activity,
- compiler_filter,
- timeout,
- simulate)
- self.app_runner.add_callbacks(self)
-
- self.trace_duration = trace_duration
- self.save_destination_file_path = save_destination_file_path
-
- def purge_file(self, suffix: str) -> None:
- print_utils.debug_print('iorapd-perfetto: purge file in ' +
- self._get_remote_path())
- adb_utils.delete_file_on_device(self._get_remote_path())
-
- def run(self) -> Optional[List[Tuple[str]]]:
- """Runs an app.
-
- Returns:
- A list of (metric, value) tuples.
- """
- return self.app_runner.run()
-
- def preprocess(self):
- # Sets up adb environment.
- adb_utils.root()
- adb_utils.disable_selinux()
- time.sleep(1)
-
- # Kill any existing process of this app
- adb_utils.pkill(self.app_runner.package)
-
- # Remove existing trace and compiler files
- self.purge_file(PerfettoTraceCollector.TRACE_FILE_SUFFIX)
-
- # Set perfetto trace duration prop to milliseconds.
- adb_utils.set_prop(PerfettoTraceCollector.TRACE_DURATION_PROP,
- int(self.trace_duration.total_seconds()*
- PerfettoTraceCollector.MS_PER_SEC))
-
- if not iorapd_utils.stop_iorapd():
- raise RuntimeError('Cannot stop iorapd!')
-
- if not iorapd_utils.enable_iorapd_perfetto():
- raise RuntimeError('Cannot enable perfetto!')
-
- if not iorapd_utils.disable_iorapd_readahead():
- raise RuntimeError('Cannot disable readahead!')
-
- if not iorapd_utils.start_iorapd():
- raise RuntimeError('Cannot start iorapd!')
-
- # Drop all caches to get cold starts.
- adb_utils.vm_drop_cache()
-
- def postprocess(self, pre_launch_timestamp: str):
- # Kill any existing process of this app
- adb_utils.pkill(self.app_runner.package)
-
- iorapd_utils.disable_iorapd_perfetto()
-
- if self.save_destination_file_path is not None:
- adb_utils.pull_file(self._get_remote_path(),
- self.save_destination_file_path)
-
- def metrics_selector(self, am_start_output: str,
- pre_launch_timestamp: str) -> str:
- """Parses the metric after app startup by reading from logcat in a blocking
- manner until all metrics have been found".
-
- Returns:
- An empty string because the metric needs no further parsing.
- """
- if not self._wait_for_perfetto_trace(pre_launch_timestamp):
- raise RuntimeError('Could not save perfetto app trace file!')
-
- return ''
-
- def _wait_for_perfetto_trace(self, pre_launch_timestamp) -> Optional[str]:
- """ Waits for the perfetto trace being saved to file.
-
- The string is in the format of r".*Perfetto TraceBuffer saved to file:
- <file path>.*"
-
- Returns:
- the string what the program waits for. If the string doesn't show up,
- return None.
- """
- pattern = re.compile(r'.*Perfetto TraceBuffer saved to file: {}.*'.
- format(self._get_remote_path()))
-
- # The pre_launch_timestamp is longer than what the datetime can parse. Trim
- # last three digits to make them align. For example:
- # 2019-07-02 23:20:06.972674825999 -> 2019-07-02 23:20:06.972674825
- assert len(pre_launch_timestamp) == len('2019-07-02 23:20:06.972674825')
- timestamp = datetime.datetime.strptime(pre_launch_timestamp[:-3],
- '%Y-%m-%d %H:%M:%S.%f')
-
- # The timeout of perfetto trace is longer than the normal app run timeout.
- timeout_dt = self.app_runner.timeout * PerfettoTraceCollector._COLLECTOR_TIMEOUT_MULTIPLIER
- timeout_end = timestamp + datetime.timedelta(seconds=timeout_dt)
-
- return logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
- pattern,
- timeout_end)
-
- def _get_remote_path(self):
- # For example: android.music%2Fmusic.TopLevelActivity.perfetto_trace.pb
- return iorapd_utils._iorapd_path_to_data_file(self.app_runner.package,
- self.app_runner.activity,
- PerfettoTraceCollector.TRACE_FILE_SUFFIX)
diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py b/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py
deleted file mode 100644
index 8d94fc58bede..000000000000
--- a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-
-"""Unit tests for the data_frame.py script."""
-import os
-import sys
-from pathlib import Path
-from datetime import timedelta
-
-from mock import call, patch
-from perfetto_trace_collector import PerfettoTraceCollector
-
-sys.path.append(Path(os.path.realpath(__file__)).parents[2])
-from app_startup.lib.app_runner import AppRunner
-
-RUNNER = PerfettoTraceCollector(package='music',
- activity='MainActivity',
- compiler_filter=None,
- timeout=10,
- simulate=False,
- trace_duration = timedelta(milliseconds=1000),
- # No actual file will be created. Just to
- # check the command.
- save_destination_file_path='/tmp/trace.pb')
-
-def _mocked_run_shell_command(*args, **kwargs):
- if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
- return (True, '9999')
- else:
- return (True, '')
-
-@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern')
-@patch('lib.cmd_utils.run_shell_command')
-def test_perfetto_trace_collector_preprocess(mock_run_shell_command,
- mock_blocking_wait_for_logcat_pattern):
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!"
-
- RUNNER.preprocess()
-
- calls = [call('adb root'),
- call('adb shell "getenforce"'),
- call('adb shell "setenforce 0"'),
- call('adb shell "stop"'),
- call('adb shell "start"'),
- call('adb wait-for-device'),
- call('adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"'),
- call(
- 'adb shell "[[ -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' ]] '
- '&& rm -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' || exit 0"'),
- call('adb shell "setprop "iorapd.perfetto.trace_duration_ms" "1000""'),
- call(
- 'bash -c "source {}; iorapd_stop"'.format(
- AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call(
- 'bash -c "source {}; iorapd_perfetto_enable"'.format(
- AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call(
- 'bash -c "source {}; iorapd_readahead_disable"'.format(
- AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call(
- 'bash -c "source {}; iorapd_start"'.format(
- AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')]
-
- mock_run_shell_command.assert_has_calls(calls)
-
-@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern')
-@patch('lib.cmd_utils.run_shell_command')
-def test_perfetto_trace_collector_postprocess(mock_run_shell_command,
- mock_blocking_wait_for_logcat_pattern):
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!"
-
- RUNNER.postprocess('2019-07-02 23:20:06.972674825')
-
- calls = [call('adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"'),
- call(
- 'bash -c "source {}; iorapd_perfetto_disable"'.format(
- AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call('adb pull '
- '"/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb" '
- '"/tmp/trace.pb"')]
-
- mock_run_shell_command.assert_has_calls(calls)
diff --git a/startop/scripts/app_startup/parse_metrics b/startop/scripts/app_startup/parse_metrics
deleted file mode 100755
index 3fa1462bc56e..000000000000
--- a/startop/scripts/app_startup/parse_metrics
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-usage() {
- cat <<EOF
-Usage: launch_application package activity | parse_metrics --package <name> --timestamp <timestamp> [OPTIONS]...
-
- Reads from stdin the result of 'am start' metrics. May also parse logcat
- for additional metrics.
-
- Output form:
-
- MetricName_unit=numeric_value
- MetricName2_unit=numeric_value2
-
- This may block until all desired metrics are parsed from logcat.
- To get a list of metrics without doing real parsing, use --simulate.
-
- To add package-specific metrics, add a script called 'metrics/\$full_package_name'
- that exposes additional metrics in same way as above.
-
- (required)
- -p, --package <name> package of the app that is being used
- -ts, --timestamp <name> logcat timestamp [only looks at logcat entries after this timestamp].
-
- (optional)
- -s, --simulate prints dummy values instead of real metrics
- -a, --activity <name> activity to use (default: inferred)
- -h, --help usage information (this)
- -v, --verbose enable extra verbose printing
- -t, --timeout <sec> how many seconds to timeout when trying to wait for logcat to change
- -rfd, --reportfullydrawn wait for report fully drawn (default: off)
-EOF
-}
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-report_fully_drawn="n"
-package=""
-activity=""
-timeout=5
-simulate="n"
-parse_arguments() {
- while [[ $# -gt 0 ]]; do
- case "$1" in
- -h|--help)
- usage
- exit 0
- ;;
- -p|--package)
- package="$2"
- shift
- ;;
- -a|--activity)
- activity="$2"
- shift
- ;;
- -v|--verbose)
- export verbose="y"
- ;;
- -t|--timeout)
- timeout="$2"
- shift
- ;;
- -ts|--timestamp)
- timestamp="$2"
- shift
- ;;
- -s|--simulate)
- simulate="y"
- ;;
- -rfd|--reportfullydrawn)
- report_fully_drawn="y"
- ;;
-
-
- *)
- echo "Invalid argument: $1" >&2
- exit 1
- esac
- shift
- done
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
- usage
- exit 1
-else
- parse_arguments "$@"
-
- # if we do not have have package exit early with an error
- [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 64
-
- # ignore timestamp for --simulate. it's optional.
- if [[ $simulate == y ]]; then
- timestamp=0
- fi
-
- # if we do not have timestamp, exit early with an error
- [[ "$timestamp" == "" ]] && echo "--timestamp not specified" 1>&2 && exit 64
-
- if [[ "$activity" == "" ]] && [[ "$simulate" != "y" ]]; then
- activity="$(get_activity_name "$package")"
- if [[ "$activity" == "" ]]; then
- echo "Activity name could not be found, invalid package name?" 1>&2
- exit 64
- else
- verbose_print "Activity name inferred: " "$activity"
- fi
- fi
-fi
-
-parse_metric_from_logcat() {
- local metric_name="$1"
- local pattern="$2"
- local re_pattern="$3"
- local retcode
- local result
- local sec
- local ms
-
- # parse logcat for 'Displayed...' and that other one...
-
- # 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
- verbose_print "parse_metric_from_logcat: $re_pattern"
-
-
- echo -ne "$metric_name="
-
- if [[ $simulate == y ]]; then
- echo "-1"
- return 0
- fi
-
- result="$(logcat_extract_pattern "$timeout" "$timestamp" "$pattern" "$re_pattern")"
- retcode=$?
-
- if [[ $retcode -ne 0 ]]; then
- # Timed out before finding the pattern. Could also mean the pattern is wrong.
- echo "Parse $re_pattern from logcat TIMED OUT after $timeout seconds." >&2
- echo "-$?"
- return $retcode
- fi
-
- # "10s123ms" -> "10s123"
- result=${result/ms/}
- if [[ $result =~ s ]]; then
- ms=${result/*s/}
- sec=${result/s*/}
- else
- sec=0
- ms=$result
- fi
- ((result=sec*1000+ms))
-
- echo "$result"
- return $retcode
-}
-
-
-total_time="-1"
-if [[ $simulate != y ]]; then
- verbose_print 'logcat timestamp NOW: ' $(logcat_save_timestamp)
-
- # parse stdin for 'am start' result
- while read -t "$timeout" -r input_line; do
- verbose_print 'stdin:' "$input_line"
- if [[ $input_line == *TotalTime:* ]]; then
- total_time="$(echo "$input_line" | sed 's/TotalTime: \([[:digit:]]\+\)/\1/g')"
- # but keep reading the rest from stdin until <EOF>
- fi
- done
-fi
-
-echo "TotalTime_ms=$total_time"
-
-# parse logcat for 'Displayed...' and that other one...
-
-# 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
-pattern="ActivityTaskManager: Displayed ${package}"
-re_pattern='.*Displayed[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
-
-parse_metric_from_logcat "Displayed_ms" "$pattern" "$re_pattern"
-
-# Only track ReportFullyDrawn with --reportfullydrawn/-rfd flags
-if [[ $report_fully_drawn == y ]]; then
- # 01-16 17:31:44.550 11172 11204 I ActivityTaskManager: Fully drawn com.google.android.GoogleCamera/com.android.camera.CameraLauncher: +10s897ms
- pattern="ActivityTaskManager: Fully drawn ${package}"
- #re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*'
- re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
-
- parse_metric_from_logcat "Fully_drawn_ms" "$pattern" "$re_pattern"
-fi
-
-# also call into package-specific scripts if there are additional metrics
-if [[ -x "$DIR/metrics/$package" ]]; then
- source "$DIR/metrics/$package" "$timestamp"
-else
- verbose_print parse_metrics: no per-package metrics script found at "$DIR/metrics/$package"
-fi
diff --git a/startop/scripts/app_startup/query_compiler_filter.py b/startop/scripts/app_startup/query_compiler_filter.py
deleted file mode 100755
index ea14264b4a1c..000000000000
--- a/startop/scripts/app_startup/query_compiler_filter.py
+++ /dev/null
@@ -1,232 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-#
-# Query the current compiler filter for an application by its package name.
-# (By parsing the results of the 'adb shell dumpsys package $package' command).
-# The output is a string "$compilation_filter $compilation_reason $isa".
-#
-# See --help for more details.
-#
-# -----------------------------------
-#
-# Sample usage:
-#
-# $> ./query_compiler_filter.py --package com.google.android.calculator
-# speed-profile unknown arm64
-#
-
-import argparse
-import os
-import re
-import sys
-
-# TODO: refactor this with a common library file with analyze_metrics.py
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-
-from typing import List, NamedTuple, Iterable
-
-_DEBUG_FORCE = None # Ignore -d/--debug if this is not none.
-
-def parse_options(argv: List[str] = None):
- """Parse command line arguments and return an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Query the compiler filter for a package.")
- # argparse considers args starting with - and -- optional in --help, even though required=True.
- # by using a named argument group --help will clearly say that it's required instead of optional.
- required_named = parser.add_argument_group('required named arguments')
- required_named.add_argument('-p', '--package', action='store', dest='package', help='package of the application', required=True)
-
- # optional arguments
- # use a group here to get the required arguments to appear 'above' the optional arguments in help.
- optional_named = parser.add_argument_group('optional named arguments')
- optional_named.add_argument('-i', '--isa', '--instruction-set', action='store', dest='instruction_set', help='which instruction set to select. defaults to the first one available if not specified.', choices=('arm64', 'arm', 'x86_64', 'x86'))
- optional_named.add_argument('-s', '--simulate', dest='simulate', action='store_true', help='Print which commands will run, but don\'t run the apps')
- optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
-
- return parser.parse_args(argv)
-
-def remote_dumpsys_package(package: str, simulate: bool) -> str:
- # --simulate is used for interactive debugging/development, but also for the unit test.
- if simulate:
- return """
-Dexopt state:
- [%s]
- path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
- arm64: [status=speed-profile] [reason=unknown]
- path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
- arm: [status=speed] [reason=first-boot]
- path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
- x86: [status=quicken] [reason=install]
-""" %(package, package, package, package)
-
- code, res = cmd_utils.execute_arbitrary_command(['adb', 'shell', 'dumpsys',
- 'package', package],
- simulate=False,
- timeout=5,
- shell=False)
- if code:
- return res
- else:
- raise AssertionError("Failed to dumpsys package, errors = %s", res)
-
-ParseTree = NamedTuple('ParseTree', [('label', str), ('children', List['ParseTree'])])
-DexoptState = ParseTree # With the Dexopt state: label
-ParseResult = NamedTuple('ParseResult', [('remainder', List[str]), ('tree', ParseTree)])
-
-def find_parse_subtree(parse_tree: ParseTree, match_regex: str) -> ParseTree:
- if re.match(match_regex, parse_tree.label):
- return parse_tree
-
- for node in parse_tree.children:
- res = find_parse_subtree(node, match_regex)
- if res:
- return res
-
- return None
-
-def find_parse_children(parse_tree: ParseTree, match_regex: str) -> Iterable[ParseTree]:
- for node in parse_tree.children:
- if re.match(match_regex, node.label):
- yield node
-
-def parse_tab_subtree(label: str, str_lines: List[str], separator=' ', indent=-1) -> ParseResult:
- children = []
-
- get_indent_level = lambda line: len(line) - len(line.lstrip())
-
- line_num = 0
-
- keep_going = True
- while keep_going:
- keep_going = False
-
- for line_num in range(len(str_lines)):
- line = str_lines[line_num]
- current_indent = get_indent_level(line)
-
- print_utils.debug_print("INDENT=%d, LINE=%s" %(current_indent, line))
-
- current_label = line.lstrip()
-
- # skip empty lines
- if line.lstrip() == "":
- continue
-
- if current_indent > indent:
- parse_result = parse_tab_subtree(current_label, str_lines[line_num+1::], separator, current_indent)
- str_lines = parse_result.remainder
- children.append(parse_result.tree)
- keep_going = True
- else:
- # current_indent <= indent
- keep_going = False
-
- break
-
- new_remainder = str_lines[line_num::]
- print_utils.debug_print("NEW REMAINDER: ", new_remainder)
-
- parse_tree = ParseTree(label, children)
- return ParseResult(new_remainder, parse_tree)
-
-def parse_tab_tree(str_tree: str, separator=' ', indentation_level=-1) -> ParseTree:
-
- label = None
- lst = []
-
- line_num = 0
- line_lst = str_tree.split("\n")
-
- return parse_tab_subtree("", line_lst, separator, indentation_level).tree
-
-def parse_dexopt_state(dumpsys_tree: ParseTree) -> DexoptState:
- res = find_parse_subtree(dumpsys_tree, "Dexopt(\s+)state[:]?")
- if not res:
- raise AssertionError("Could not find the Dexopt state")
- return res
-
-def find_first_compiler_filter(dexopt_state: DexoptState, package: str, instruction_set: str) -> str:
- lst = find_all_compiler_filters(dexopt_state, package)
-
- print_utils.debug_print("all compiler filters: ", lst)
-
- for compiler_filter_info in lst:
- if not instruction_set:
- return compiler_filter_info
-
- if compiler_filter_info.isa == instruction_set:
- return compiler_filter_info
-
- return None
-
-CompilerFilterInfo = NamedTuple('CompilerFilterInfo', [('isa', str), ('status', str), ('reason', str)])
-
-def find_all_compiler_filters(dexopt_state: DexoptState, package: str) -> List[CompilerFilterInfo]:
-
- lst = []
- package_tree = find_parse_subtree(dexopt_state, re.escape("[%s]" %package))
-
- if not package_tree:
- raise AssertionError("Could not find any package subtree for package %s" %(package))
-
- print_utils.debug_print("package tree: ", package_tree)
-
- for path_tree in find_parse_children(package_tree, "path: "):
- print_utils.debug_print("path tree: ", path_tree)
-
- matchre = re.compile("([^:]+):\s+\[status=([^\]]+)\]\s+\[reason=([^\]]+)\]")
-
- for isa_node in find_parse_children(path_tree, matchre):
-
- matches = re.match(matchre, isa_node.label).groups()
-
- info = CompilerFilterInfo(*matches)
- lst.append(info)
-
- return lst
-
-def main() -> int:
- opts = parse_options()
- cmd_utils._debug = opts.debug
- if _DEBUG_FORCE is not None:
- cmd_utils._debug = _DEBUG_FORCE
- print_utils.debug_print("parsed options: ", opts)
-
- # Note: This can often 'fail' if the package isn't actually installed.
- package_dumpsys = remote_dumpsys_package(opts.package, opts.simulate)
- print_utils.debug_print("package dumpsys: ", package_dumpsys)
- dumpsys_parse_tree = parse_tab_tree(package_dumpsys, package_dumpsys)
- print_utils.debug_print("parse tree: ", dumpsys_parse_tree)
- dexopt_state = parse_dexopt_state(dumpsys_parse_tree)
-
- filter = find_first_compiler_filter(dexopt_state, opts.package, opts.instruction_set)
-
- if filter:
- print(filter.status, end=' ')
- print(filter.reason, end=' ')
- print(filter.isa)
- else:
- print("ERROR: Could not find any compiler-filter for package %s, isa %s" %(opts.package, opts.instruction_set), file=sys.stderr)
- return 1
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/startop/scripts/app_startup/query_compiler_filter_test.py b/startop/scripts/app_startup/query_compiler_filter_test.py
deleted file mode 100755
index a751a43d1d6c..000000000000
--- a/startop/scripts/app_startup/query_compiler_filter_test.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for the query_compiler_filter.py script.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> ./query_compiler_filter.py
- $> pytest query_compiler_filter.py
- $> python -m pytest query_compiler_filter.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-from contextlib import contextmanager
-import io
-import shlex
-import sys
-import typing
-
-# pip imports
-import pytest
-
-# local imports
-import query_compiler_filter as qcf
-
-@contextmanager
-def redirect_stdout_stderr():
- """Redirect stdout/stderr to a new StringIO for duration of context."""
- old_stdout = sys.stdout
- old_stderr = sys.stderr
- new_stdout = io.StringIO()
- sys.stdout = new_stdout
- new_stderr = io.StringIO()
- sys.stderr = new_stderr
- try:
- yield (new_stdout, new_stderr)
- finally:
- sys.stdout = old_stdout
- sys.stderr = old_stderr
- # Seek back to the beginning so we can read whatever was written into it.
- new_stdout.seek(0)
- new_stderr.seek(0)
-
-@contextmanager
-def replace_argv(argv):
- """ Temporarily replace argv for duration of this context."""
- old_argv = sys.argv
- sys.argv = [sys.argv[0]] + argv
- try:
- yield
- finally:
- sys.argv = old_argv
-
-def exec_main(argv):
- """Run the query_compiler_filter main function with the provided arguments.
-
- Returns the stdout result when successful, assertion failure otherwise.
- """
- try:
- with redirect_stdout_stderr() as (the_stdout, the_stderr):
- with replace_argv(argv):
- code = qcf.main()
- assert 0 == code, the_stderr.readlines()
-
- all_lines = the_stdout.readlines()
- return "".join(all_lines)
- finally:
- the_stdout.close()
- the_stderr.close()
-
-def test_query_compiler_filter():
- # no --instruction-set specified: provide whatever was the 'first' filter.
- assert exec_main(['--simulate',
- '--package', 'com.google.android.apps.maps']) == \
- "speed-profile unknown arm64\n"
-
- # specifying an instruction set finds the exact compiler filter match.
- assert exec_main(['--simulate',
- '--package', 'com.google.android.apps.maps',
- '--instruction-set', 'arm64']) == \
- "speed-profile unknown arm64\n"
-
- assert exec_main(['--simulate',
- '--package', 'com.google.android.apps.maps',
- '--instruction-set', 'arm']) == \
- "speed first-boot arm\n"
-
- assert exec_main(['--simulate',
- '--debug',
- '--package', 'com.google.android.apps.maps',
- '--instruction-set', 'x86']) == \
- "quicken install x86\n"
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch
deleted file mode 100755
index 31f625334b1e..000000000000
--- a/startop/scripts/app_startup/run_app_with_prefetch
+++ /dev/null
@@ -1,487 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-usage() {
- cat <<EOF
-Usage: run_app_with_prefetch --package <name> [OPTIONS]...
-
- -p, --package <name> package of the app to test
- -a, --activity <name> activity to use
- -h, --help usage information (this)
- -v, --verbose enable extra verbose printing
- -i, --input <file> trace file protobuf (default 'TraceFile.pb')
- -r, --readahead <mode> cold, warm, fadvise, mlock (default 'warm')
- -w, --when <when> aot or jit (default 'jit')
- -c, --count <count> how many times to run (default 1)
- -s, --sleep <sec> how long to sleep after readahead
- -t, --timeout <sec> how many seconds to timeout in between each app run (default 10)
- -o, --output <file.csv> what file to write the performance results into as csv (default stdout)
-EOF
-}
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/../iorap/common"
-
-report_fully_drawn="n"
-needs_trace_file="n"
-input_file=""
-package=""
-mode='warm'
-count=2
-sleep_time=2
-timeout=10
-output="" # stdout by default
-when="jit"
-parse_arguments() {
- while [[ $# -gt 0 ]]; do
- case "$1" in
- -h|--help)
- usage
- exit 0
- ;;
- -p|--package)
- package="$2"
- shift
- ;;
- -a|--activity)
- activity="$2"
- shift
- ;;
- -i|--input)
- input_file="$2"
- shift
- ;;
- -v|--verbose)
- export verbose="y"
- ;;
- -r|--readahead)
- mode="$2"
- shift
- ;;
- -rfd|--reportfullydrawn)
- report_fully_drawn="y"
- shift
- ;;
- -c|--count)
- count="$2"
- ((count+=1))
- shift
- ;;
- -s|--sleep)
- sleep_time="$2"
- shift
- ;;
- -t|--timeout)
- timeout="$2"
- shift
- ;;
- -o|--output)
- output="$2"
- shift
- ;;
- -w|--when)
- when="$2"
- shift
- ;;
- --compiler-filter)
- compiler_filter="$2"
- shift
- ;;
- *)
- echo "Invalid argument: $1" >&2
- exit 1
- esac
- shift
- done
-
- if [[ $when == "aot" ]]; then
- # TODO: re-implement aot later for experimenting.
- echo "Error: --when $when is unsupported" >&2
- exit 1
- elif [[ $when != "jit" ]]; then
- echo "Error: --when must be one of (aot jit)." >&2
- exit 1
- fi
-}
-
-echo_to_output_file() {
- if [[ "x$output" != x ]]; then
- echo "$@" >> $output
- fi
- # Always echo to stdout as well.
- echo "$@"
-}
-
-find_package_path() {
- local pkg="$1"
-
- res="$(adb shell find "/data/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
- if [[ -z $res ]]; then
- res="$(adb shell find "/system/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
- fi
- echo "$res"
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
- usage
- exit 1
-else
- parse_arguments "$@"
-
- # if we do not have have package exit early with an error
- [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1
-
- if [[ $mode != "cold" && $mode != "warm" ]]; then
- needs_trace_file="y"
- if [[ -z "$input_file" ]] || ! [[ -f $input_file ]]; then
- echo "--input not specified" 1>&2
- exit 1
- fi
- fi
-
- if [[ "$activity" == "" ]]; then
- activity="$(get_activity_name "$package")"
- if [[ "$activity" == "" ]]; then
- echo "Activity name could not be found, invalid package name?" 1>&2
- exit 1
- else
- verbose_print "Activity name inferred: " "$activity"
- fi
- fi
-fi
-
-adb root > /dev/null
-
-if [[ ($when == jit) || ($when == aot) ]] && [[ "$(adb shell getenforce)" != "Permissive" ]]; then
- echo "Disable selinux permissions and restart framework."
- adb shell setenforce 0
- adb shell stop
- adb shell start
- adb wait-for-device
-fi
-
-# TODO: set performance governor etc, preferrably only once
-# before every single app run.
-
-# Kill everything before running.
-remote_pkill "$package"
-sleep 1
-
-timings_array=()
-
-package_path="$(find_package_path "$package")"
-if [[ $? -ne 0 ]]; then
- echo "Failed to detect package path for '$package'" >&2
- exit 1
-fi
-verbose_print "Package was in path '$package_path'"
-
-application_trace_file_path="$package_path/TraceFile.pb"
-trace_file_directory="$package_path"
-if [[ $needs_trace_file == y ]]; then
- # system server always passes down the package path in a hardcoded spot.
- if [[ $when == "jit" ]]; then
- if ! iorapd_compiler_install_trace_file "$package" "$activity" "$input_file"; then
- echo "Error: Failed to install compiled TraceFile.pb for '$package/$activity'" >&2
- exit 1
- fi
- keep_application_trace_file="y"
- else
- echo "TODO: --readahead=aot is non-functional and needs to be fixed." >&2
- exit 1
- # otherwise use a temporary directory to get normal non-jit behavior.
- trace_file_directory="/data/local/tmp/prefetch/$package"
- adb shell mkdir -p "$trace_file_directory"
- verbose_print adb push "$input_file" "$trace_file_directory/TraceFile.pb"
- adb push "$input_file" "$trace_file_directory/TraceFile.pb"
- fi
-fi
-
-# Everything other than JIT: remove the trace file,
-# otherwise system server activity hints will kick in
-# and the new just-in-time app pre-warmup will happen.
-if [[ $keep_application_trace_file == "n" ]]; then
- iorapd_compiler_purge_trace_file "$package" "$activity"
-fi
-
-# Perform AOT readahead/pinning/etc when an application is about to be launched.
-# For JIT readahead, we allow the system to handle it itself (this is a no-op).
-#
-# For warm, cold, etc modes which don't need readahead this is always a no-op.
-perform_aot() {
- local the_when="$1" # user: aot, jit
- local the_mode="$2" # warm, cold, fadvise, mlock, etc.
-
- # iorapd readahead for jit+(mlock/fadvise)
- if [[ $the_when == "jit" && $the_mode != 'warm' && $the_mode != 'cold' ]]; then
- iorapd_readahead_enable
- return 0
- fi
-
- if [[ $the_when != "aot" ]]; then
- # TODO: just in time implementation.. should probably use system server.
- return 0
- fi
-
- # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
- if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
-
- # TODO: add activity_hint_sender.exp
- verbose_print "starting with package=$package package_path=$trace_file_directory"
- coproc hint_sender_fd { $ANDROID_BUILD_TOP/system/iorap/src/sh/activity_hint_sender.exp "$package" "$trace_file_directory" "$the_mode"; }
- hint_sender_pid=$!
- verbose_print "Activity hint sender began"
-
- notification_success="n"
- while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
- verbose_print "$hint_sender_output"
- if [[ "$hint_sender_output" == "Press any key to send completed event..."* ]]; then
- verbose_print "WE DID SEE NOTIFICATION SUCCESS."
- notification_success='y'
- # Give it some time to actually perform the readaheads.
- sleep $sleep_time
- break
- fi
- done
-
- if [[ $notification_success == 'n' ]]; then
- echo "[FATAL] Activity hint notification failed." 1>&2
- exit 1
- fi
- fi
-}
-
-# Perform cleanup at the end of each loop iteration.
-perform_post_launch_cleanup() {
- local the_when="$1" # user: aot, jit
- local the_mode="$2" # warm, cold, fadvise, mlock, etc.
- local logcat_timestamp="$3" # timestamp from before am start.
- local res
-
- if [[ $the_when != "aot" ]]; then
- if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
- # Validate that readahead completes.
- # If this fails for some reason, then this will also discard the timing of the run.
- iorapd_readahead_wait_until_finished "$package" "$activity" "$logcat_timestamp" "$timeout"
- res=$?
-
- iorapd_readahead_disable
-
- return $res
- fi
- # Don't need to do anything for warm or cold.
- return 0
- fi
-
- # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
- if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
- # Clean up the hint sender by telling it that the launch was completed,
- # and to shutdown the watcher.
- echo "Done\n" >&"${hint_sender_fd[1]}"
-
- while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
- verbose_print "$hint_sender_output"
- done
-
- wait $hint_sender_pid
- fi
-}
-
-configure_compiler_filter() {
- local the_compiler_filter="$1"
- local the_package="$2"
- local the_activity="$3"
-
- if [[ -z $the_compiler_filter ]]; then
- verbose_print "No --compiler-filter specified, don't need to force it."
- return 0
- fi
-
- local current_compiler_filter_info="$("$DIR"/query_compiler_filter.py --package "$the_package")"
- local res=$?
- if [[ $res -ne 0 ]]; then
- return $res
- fi
-
- local current_compiler_filter
- local current_reason
- local current_isa
- read current_compiler_filter current_reason current_isa <<< "$current_compiler_filter_info"
-
- verbose_print "Compiler Filter="$current_compiler_filter "Reason="$current_reason "Isa="$current_isa
-
- # Don't trust reasons that aren't 'unknown' because that means we didn't manually force the compilation filter.
- # (e.g. if any automatic system-triggered compilations are not unknown).
- if [[ $current_reason != "unknown" ]] || [[ $current_compiler_filter != $the_compiler_filter ]]; then
- verbose_print "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity"
- "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity"
- res=$?
- else
- verbose_print "Queried compiler-filter matched requested compiler-filter, skip forcing."
- res=0
- fi
-
- return $res
-}
-
-# Ensure the APK is currently compiled with whatever we passed in via --compiler-filter.
-# No-op if this option was not passed in.
-configure_compiler_filter "$compiler_filter" "$package" "$activity" || exit 1
-
-# convert 'a=b\nc=d\ne=f\n...' into 'b,d,f,...'
-parse_metrics_output_string() {
- # single string with newlines in it.
- local input="$1"
-
- local metric_name
- local metric_value
- local rest
-
- local all_metrics=()
-
- # (n1=v1 n2=v2 n3=v3 ...)
- readarray -t all_metrics <<< "$input"
-
- local kv_pair=()
- local i
-
- for i in "${all_metrics[@]}"
- do
- verbose_print "parse_metrics_output: element '$i'"
- # name=value
-
- IFS='=' read -r metric_name metric_value rest <<< "$i"
-
- verbose_print "parse_metrics_output: metric_value '$metric_value'"
-
- # (value1 value2 value3 ...)
- all_metrics+=(${metric_value})
- done
-
- # "value1,value2,value3,..."
- join_by ',' "${all_metrics[@]}"
-}
-
-# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
-parse_metrics_output() {
- local metric_name
- local metric_value
- local rest
-
- local all_metrics=()
-
- while IFS='=' read -r metric_name metric_value rest; do
- verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
- all_metrics+=($metric_value)
- done
-
- join_by ',' "${all_metrics[@]}"
-}
-
-# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
-parse_metrics_header() {
- local metric_name
- local metric_value
- local rest
-
- local all_metrics=()
-
- while IFS='=' read -r metric_name metric_value rest; do
- verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
- all_metrics+=($metric_name)
- done
-
- join_by ',' "${all_metrics[@]}"
-}
-
-if [[ $report_fully_drawn == y ]]; then
- metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate --reportfullydrawn | parse_metrics_header)"
-else
- metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)"
-fi
-
-# TODO: This loop logic could probably be moved into app_startup_runner.py
-for ((i=0;i<count;++i)) do
- verbose_print "=========================================="
- verbose_print "==== ITERATION $i ===="
- verbose_print "=========================================="
- if [[ $mode != "warm" ]]; then
- # The package must be killed **before** we drop caches, otherwise pages will stay resident.
- verbose_print "Kill package for non-warm start."
- remote_pkill "$package"
- verbose_print "Drop caches for non-warm start."
- # Drop all caches to get cold starts.
- adb shell "echo 3 > /proc/sys/vm/drop_caches"
- fi
-
- perform_aot "$when" "$mode"
-
- verbose_print "Running with timeout $timeout"
-
- pre_launch_timestamp="$(logcat_save_timestamp)"
-
- # TODO: multiple metrics output.
-
-if [[ $report_fully_drawn == y ]]; then
- total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" --reportfullydrawn | parse_metrics_output)"
-else
- total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" | parse_metrics_output)"
-fi
-
- if [[ $? -ne 0 ]]; then
- echo "WARNING: Skip bad result, try iteration again." >&2
- ((i=i-1))
- continue
- fi
-
- perform_post_launch_cleanup "$when" "$mode" "$pre_launch_timestamp"
-
- if [[ $? -ne 0 ]]; then
- echo "WARNING: Skip bad cleanup, try iteration again." >&2
- ((i=i-1))
- continue
- fi
-
- echo "Iteration $i. Total time was: $total_time"
-
- timings_array+=("$total_time")
-done
-
-# drop the first result which is usually garbage.
-timings_array=("${timings_array[@]:1}")
-
-# Print the CSV header first.
-echo_to_output_file "$metrics_header"
-
-# Print out interactive/debugging timings and averages.
-# Other scripts should use the --output flag and parse the CSV.
-for tim in "${timings_array[@]}"; do
- echo_to_output_file "$tim"
-done
-
-if [[ x$output != x ]]; then
- echo " Saved results to '$output'"
-fi
-
-if [[ $needs_trace_file == y ]] ; then
- iorapd_compiler_purge_trace_file "$package" "$activity"
-fi
-
-# Kill the process to ensure AM isn't keeping it around.
-remote_pkill "$package"
-
-exit 0
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
deleted file mode 100755
index 2f1eff2c41f6..000000000000
--- a/startop/scripts/app_startup/run_app_with_prefetch.py
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Runner of one test given a setting.
-
-Run app and gather the measurement in a certain configuration.
-Print the result to stdout.
-See --help for more details.
-
-Sample usage:
- $> ./python run_app_with_prefetch.py -p com.android.settings -a
- com.android.settings.Settings -r fadvise -i input
-
-"""
-
-import argparse
-import os
-import sys
-import time
-from typing import List, Tuple, Optional
-
-# local imports
-import lib.adb_utils as adb_utils
-from lib.app_runner import AppRunner, AppRunnerListener
-
-# global variables
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(DIR))
-import lib.print_utils as print_utils
-import lib.cmd_utils as cmd_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-
-class PrefetchAppRunner(AppRunnerListener):
- def __init__(self,
- package: str,
- activity: Optional[str],
- readahead: str,
- compiler_filter: Optional[str],
- timeout: Optional[int],
- simulate: bool,
- debug: bool,
- input:Optional[str],
- **kwargs):
- self.app_runner = AppRunner(package,
- activity,
- compiler_filter,
- timeout,
- simulate)
- self.app_runner.add_callbacks(self)
-
- self.simulate = simulate
- self.readahead = readahead
- self.debug = debug
- self.input = input
- print_utils.DEBUG = self.debug
- cmd_utils.SIMULATE = self.simulate
-
-
- def run(self) -> Optional[List[Tuple[str]]]:
- """Runs an app.
-
- Returns:
- A list of (metric, value) tuples.
- """
- return self.app_runner.run()
-
- def preprocess(self):
- passed = self.validate_options()
- if not passed:
- return
-
- # Sets up adb environment.
- adb_utils.root()
- adb_utils.disable_selinux()
- time.sleep(1)
-
- # Kill any existing process of this app
- adb_utils.pkill(self.app_runner.package)
-
- if self.readahead != 'warm':
- print_utils.debug_print('Drop caches for non-warm start.')
- # Drop all caches to get cold starts.
- adb_utils.vm_drop_cache()
-
- if self.readahead != 'warm' and self.readahead != 'cold':
- iorapd_utils.enable_iorapd_readahead()
-
- def postprocess(self, pre_launch_timestamp: str):
- passed = self._perform_post_launch_cleanup(pre_launch_timestamp)
- if not passed and not self.app_runner.simulate:
- print_utils.error_print('Cannot perform post launch cleanup!')
- return None
-
- # Kill any existing process of this app
- adb_utils.pkill(self.app_runner.package)
-
- def _perform_post_launch_cleanup(self, logcat_timestamp: str) -> bool:
- """Performs cleanup at the end of each loop iteration.
-
- Returns:
- A bool indicates whether the cleanup succeeds or not.
- """
- if self.readahead != 'warm' and self.readahead != 'cold':
- passed = iorapd_utils.wait_for_iorapd_finish(self.app_runner.package,
- self.app_runner.activity,
- self.app_runner.timeout,
- self.debug,
- logcat_timestamp)
-
- if not passed:
- return passed
-
- return iorapd_utils.disable_iorapd_readahead()
-
- # Don't need to do anything for warm or cold.
- return True
-
- def metrics_selector(self, am_start_output: str,
- pre_launch_timestamp: str) -> str:
- """Parses the metric after app startup by reading from logcat in a blocking
- manner until all metrics have been found".
-
- Returns:
- the total time and displayed time of app startup.
- For example: "TotalTime=123\nDisplayedTime=121
- """
- total_time = AppRunner.parse_total_time(am_start_output)
- displayed_time = adb_utils.blocking_wait_for_logcat_displayed_time(
- pre_launch_timestamp, self.app_runner.package, self.app_runner.timeout)
-
- return 'TotalTime={}\nDisplayedTime={}'.format(total_time, displayed_time)
-
- def validate_options(self) -> bool:
- """Validates the activity and trace file if needed.
-
- Returns:
- A bool indicates whether the activity is valid.
- """
- needs_trace_file = self.readahead != 'cold' and self.readahead != 'warm'
- if needs_trace_file and (self.input is None or
- not os.path.exists(self.input)):
- print_utils.error_print('--input not specified!')
- return False
-
- # Install necessary trace file. This must be after the activity checking.
- if needs_trace_file:
- passed = iorapd_utils.iorapd_compiler_install_trace_file(
- self.app_runner.package, self.app_runner.activity, self.input)
- if not cmd_utils.SIMULATE and not passed:
- print_utils.error_print('Failed to install compiled TraceFile.pb for '
- '"{}/{}"'.
- format(self.app_runner.package,
- self.app_runner.activity))
- return False
-
- return True
-
-
-
-def parse_options(argv: List[str] = None):
- """Parses command line arguments and return an argparse Namespace object."""
- parser = argparse.ArgumentParser(
- description='Run an Android application once and measure startup time.'
- )
-
- required_named = parser.add_argument_group('required named arguments')
- required_named.add_argument('-p', '--package', action='store', dest='package',
- help='package of the application', required=True)
-
- # optional arguments
- # use a group here to get the required arguments to appear 'above' the
- # optional arguments in help.
- optional_named = parser.add_argument_group('optional named arguments')
- optional_named.add_argument('-a', '--activity', action='store',
- dest='activity',
- help='launch activity of the application')
- optional_named.add_argument('-s', '--simulate', dest='simulate',
- action='store_true',
- help='simulate the process without executing '
- 'any shell commands')
- optional_named.add_argument('-d', '--debug', dest='debug',
- action='store_true',
- help='Add extra debugging output')
- optional_named.add_argument('-i', '--input', action='store', dest='input',
- help='perfetto trace file protobuf',
- default='TraceFile.pb')
- optional_named.add_argument('-r', '--readahead', action='store',
- dest='readahead',
- help='which readahead mode to use',
- default='cold',
- choices=('warm', 'cold', 'mlock', 'fadvise'))
- optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
- type=int,
- help='Timeout after this many seconds when '
- 'executing a single run.',
- default=10)
- optional_named.add_argument('--compiler-filter', dest='compiler_filter',
- action='store',
- help='Which compiler filter to use.',
- default=None)
-
- return parser.parse_args(argv)
-
-def main():
- opts = parse_options()
- runner = PrefetchAppRunner(**vars(opts))
- result = runner.run()
-
- if result is None:
- return 1
-
- print(result)
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py
deleted file mode 100644
index 8a588e4463e9..000000000000
--- a/startop/scripts/app_startup/run_app_with_prefetch_test.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-"""Unit tests for the run_app_with_prefetch_test.py script.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> ./run_app_with_prefetch_test.py
- $> pytest run_app_with_prefetch_test.py
- $> python -m pytest run_app_with_prefetch_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-import io
-import os
-import shlex
-import sys
-import tempfile
-# global imports
-from contextlib import contextmanager
-
-# pip imports
-import pytest
-# local imports
-import run_app_with_prefetch as runner
-from mock import call, patch, Mock
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from app_startup.lib.app_runner import AppRunner
-#
-# Argument Parsing Helpers
-#
-
-@contextmanager
-def ignore_stdout_stderr():
- """Ignore stdout/stderr output for duration of this context."""
- old_stdout = sys.stdout
- old_stderr = sys.stderr
- sys.stdout = io.StringIO()
- sys.stderr = io.StringIO()
- try:
- yield
- finally:
- sys.stdout = old_stdout
- sys.stderr = old_stderr
-
-@contextmanager
-def argparse_bad_argument(msg):
- """Asserts that a SystemExit is raised when executing this context.
-
- If the assertion fails, print the message 'msg'.
- """
- with pytest.raises(SystemExit, message=msg):
- with ignore_stdout_stderr():
- yield
-
-def assert_bad_argument(args, msg):
- """Asserts that the command line arguments in 'args' are malformed.
-
- Prints 'msg' if the assertion fails.
- """
- with argparse_bad_argument(msg):
- parse_args(args)
-
-def parse_args(args):
- """
- :param args: command-line like arguments as a single string
- :return: dictionary of parsed key/values
- """
- # "-a b -c d" => ['-a', 'b', '-c', 'd']
- return vars(runner.parse_options(shlex.split(args)))
-
-def default_dict_for_parsed_args(**kwargs):
- """Combines it with all of the "optional" parameters' default values."""
- d = {
- 'readahead': 'cold',
- 'simulate': None,
- 'simulate': False,
- 'debug': False,
- 'input': 'TraceFile.pb',
- 'timeout': 10,
- 'compiler_filter': None,
- 'activity': None
- }
- d.update(kwargs)
- return d
-
-def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
- """Combines default dict with all optional parameters with some mock required
- parameters.
- """
- d = {'package': 'com.fake.package'}
- if include_optional:
- d.update(default_dict_for_parsed_args())
- d.update(kwargs)
- return d
-
-def parse_optional_args(str):
- """
- Parses an argument string which already includes all the required arguments
- in default_mock_dict_for_parsed_args.
- """
- req = '--package com.fake.package'
- return parse_args('%s %s' % (req, str))
-
-def test_argparse():
- # missing arguments
- assert_bad_argument('', '-p are required')
-
- # required arguments are parsed correctly
- ad = default_dict_for_parsed_args # assert dict
- assert parse_args('--package xyz') == ad(package='xyz')
-
- assert parse_args('-p xyz') == ad(package='xyz')
-
- assert parse_args('-p xyz -s') == ad(package='xyz', simulate=True)
- assert parse_args('-p xyz --simulate') == ad(package='xyz', simulate=True)
-
- # optional arguments are parsed correctly.
- mad = default_mock_dict_for_parsed_args # mock assert dict
- assert parse_optional_args('--input trace.pb') == mad(input='trace.pb')
-
- assert parse_optional_args('--compiler-filter speed') == \
- mad(compiler_filter='speed')
-
- assert parse_optional_args('-d') == mad(debug=True)
- assert parse_optional_args('--debug') == mad(debug=True)
-
- assert parse_optional_args('--timeout 123') == mad(timeout=123)
- assert parse_optional_args('-t 456') == mad(timeout=456)
-
- assert parse_optional_args('-r warm') == mad(readahead='warm')
- assert parse_optional_args('--readahead warm') == mad(readahead='warm')
-
- assert parse_optional_args('-a act') == mad(activity='act')
- assert parse_optional_args('--activity act') == mad(activity='act')
-
-def test_main():
- args = '--package com.fake.package --activity act -s'
- opts = runner.parse_options(shlex.split(args))
- result = runner.PrefetchAppRunner(**vars(opts)).run()
- assert result == [('TotalTime', '123')]
-
-def _mocked_run_shell_command(*args, **kwargs):
- if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
- return (True, '9999')
- else:
- return (True, '')
-
-def test_preprocess_no_cache_drop():
- with patch('lib.cmd_utils.run_shell_command',
- new_callable=Mock) as mock_run_shell_command:
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- prefetch_app_runner = runner.PrefetchAppRunner(package='music',
- activity='MainActivity',
- readahead='warm',
- compiler_filter=None,
- timeout=None,
- simulate=False,
- debug=False,
- input=None)
-
- prefetch_app_runner.preprocess()
-
- calls = [call('adb root'),
- call('adb shell "getenforce"'),
- call('adb shell "setenforce 0"'),
- call('adb shell "stop"'),
- call('adb shell "start"'),
- call('adb wait-for-device'),
- call('adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"')]
- mock_run_shell_command.assert_has_calls(calls)
-
-def test_preprocess_with_cache_drop():
- with patch('lib.cmd_utils.run_shell_command',
- new_callable=Mock) as mock_run_shell_command:
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- prefetch_app_runner = runner.PrefetchAppRunner(package='music',
- activity='MainActivity',
- readahead='cold',
- compiler_filter=None,
- timeout=None,
- simulate=False,
- debug=False,
- input=None)
-
- prefetch_app_runner.preprocess()
-
- calls = [call('adb root'),
- call('adb shell "getenforce"'),
- call('adb shell "setenforce 0"'),
- call('adb shell "stop"'),
- call('adb shell "start"'),
- call('adb wait-for-device'),
- call('adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"'),
- call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')]
- mock_run_shell_command.assert_has_calls(calls)
-
-def test_preprocess_with_cache_drop_and_iorapd_enabled():
- with patch('lib.cmd_utils.run_shell_command',
- new_callable=Mock) as mock_run_shell_command:
- mock_run_shell_command.side_effect = _mocked_run_shell_command
-
- with tempfile.NamedTemporaryFile() as input:
- prefetch_app_runner = runner.PrefetchAppRunner(package='music',
- activity='MainActivity',
- readahead='fadvise',
- compiler_filter=None,
- timeout=None,
- simulate=False,
- debug=False,
- input=input.name)
-
- prefetch_app_runner.preprocess()
-
- calls = [call('adb root'),
- call('adb shell "getenforce"'),
- call('adb shell "setenforce 0"'),
- call('adb shell "stop"'),
- call('adb shell "start"'),
- call('adb wait-for-device'),
- call(
- 'adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"'),
- call('adb shell "echo 3 > /proc/sys/vm/drop_caches"'),
- call('bash -c "source {}; iorapd_readahead_enable"'.
- format(AppRunner.IORAP_COMMON_BASH_SCRIPT))]
- mock_run_shell_command.assert_has_calls(calls)
-
-@patch('lib.adb_utils.blocking_wait_for_logcat_displayed_time')
-@patch('lib.cmd_utils.run_shell_command')
-def test_postprocess_with_launch_cleanup(
- mock_run_shell_command,
- mock_blocking_wait_for_logcat_displayed_time):
- mock_run_shell_command.side_effect = _mocked_run_shell_command
- mock_blocking_wait_for_logcat_displayed_time.return_value = 123
-
- with tempfile.NamedTemporaryFile() as input:
- prefetch_app_runner = runner.PrefetchAppRunner(package='music',
- activity='MainActivity',
- readahead='fadvise',
- compiler_filter=None,
- timeout=10,
- simulate=False,
- debug=False,
- input=input.name)
-
- prefetch_app_runner.postprocess('2019-07-02 23:20:06.972674825')
-
- calls = [
- call('bash -c "source {script_path}; '
- 'iorapd_readahead_wait_until_finished '
- '\'{package}\' \'{activity}\' \'{timestamp}\' \'{timeout}\'"'.
- format(timeout=10,
- package='music',
- activity='MainActivity',
- timestamp='2019-07-02 23:20:06.972674825',
- script_path=AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call('bash -c "source {}; iorapd_readahead_disable"'.
- format(AppRunner.IORAP_COMMON_BASH_SCRIPT)),
- call('adb shell ps | grep "music" | awk \'{print $2;}\''),
- call('adb shell "kill 9999"')]
- mock_run_shell_command.assert_has_calls(calls)
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/app_startup/unlock_screen b/startop/scripts/app_startup/unlock_screen
deleted file mode 100755
index 478294c9f35d..000000000000
--- a/startop/scripts/app_startup/unlock_screen
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This turns the screen on if it's off.
-# If it's on it does nothing unless its on the home screen, in which case it opens up some background
-# menu.
-#
-# However, this menu is ignored because "am start" commands still work as expected.
-adb shell input keyevent MENU
diff --git a/startop/scripts/iorap/analyze_prefetch_file.py b/startop/scripts/iorap/analyze_prefetch_file.py
deleted file mode 100755
index 343cd54b7174..000000000000
--- a/startop/scripts/iorap/analyze_prefetch_file.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import os
-import sys
-from typing import Dict, List, NamedTuple, Tuple
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR)) # framework/base/startop/script
-import lib.print_utils as print_utils
-
-# Include generated protos.
-dir_name = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(dir_name + "/generated")
-
-from TraceFile_pb2 import *
-
-def parse_options(argv: List[str] = None):
- """Parses command line arguments and returns an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Analyze compiled_trace iorap protos.")
- required_named = parser.add_argument_group('required named arguments')
-
- required_named.add_argument('-i', dest='input', metavar='FILE',
- help='Read protobuf file as input')
-
- optional_named = parser.add_argument_group('optional named arguments')
-
- optional_named.add_argument('-up', dest='upper_percent', type=float,
- default=95.0,
- help='Only show the top-most entries up to this value.')
-
- optional_named.add_argument('-r', dest='raw', action='store_true',
- help='Output entire raw file.')
- optional_named.add_argument('-o', dest='output',
- help='The results are stored into the output file')
- optional_named.add_argument('-d', dest='debug', action='store_true'
- , help='Activity of the app to be compiled')
-
- return parser.parse_args(argv)
-
-def open_iorap_prefetch_file(file_path: str) -> TraceFile:
- with open(file_path, "rb") as f:
- tf = TraceFile()
- tf.ParseFromString(f.read())
- return tf
-
-def print_stats_summary(trace_file: TraceFile, upper_percent):
- tf_dict = convert_to_dict(trace_file)
- print_utils.debug_print(tf_dict)
-
- total_length = 0
- summaries = []
- for name, entries_list in tf_dict.items():
- summary = entries_sum(entries_list)
- summaries.append(summary)
-
- total_length += summary.length
-
- # Sort by length
- summaries.sort(reverse=True, key=lambda s: s.length)
-
- percent_sum = 0.0
- skipped_entries = 0
-
- print("===========================================")
- print("Total length: {:,} bytes".format(total_length))
- print("Displayed upper percent: {:0.2f}%".format(upper_percent))
- print("===========================================")
- print("")
- print("name,length,percent_of_total,upper_percent")
- for sum in summaries:
- percent_of_total = (sum.length * 1.0) / (total_length * 1.0) * 100.0
-
- percent_sum += percent_of_total
-
- if percent_sum > upper_percent:
- skipped_entries = skipped_entries + 1
- continue
-
- #print("%s,%d,%.2f%%" %(sum.name, sum.length, percent_of_total))
- print("{:s},{:d},{:0.2f}%,{:0.2f}%".format(sum.name, sum.length, percent_of_total, percent_sum))
-
- if skipped_entries > 0:
- print("[WARNING] Skipped {:d} entries, use -up=100 to show everything".format(skipped_entries))
-
- pass
-
-class FileEntry(NamedTuple):
- id: int
- name: str
- offset: int
- length: int
-
-class FileEntrySummary(NamedTuple):
- name: str
- length: int
-
-def entries_sum(entries: List[FileEntry]) -> FileEntrySummary:
- if not entries:
- return None
-
- summary = FileEntrySummary(name=entries[0].name, length=0)
- for entry in entries:
- summary = FileEntrySummary(summary.name, summary.length + entry.length)
-
- return summary
-
-def convert_to_dict(trace_file: TraceFile) -> Dict[str, FileEntry]:
- trace_file_index = trace_file.index
-
- # entries.id -> entry.file_name
- entries_map = {}
-
- index_entries = trace_file_index.entries
- for entry in index_entries:
- entries_map[entry.id] = entry.file_name
-
- final_map = {}
-
- file_entries_map = {}
- file_entries = trace_file.list.entries
- for entry in file_entries:
- print_utils.debug_print(entry)
-
- lst = file_entries_map.get(entry.index_id, [])
- file_entries_map[entry.index_id] = lst
-
- file_name = entries_map[entry.index_id]
- file_entry = \
- FileEntry(id=entry.index_id, name=file_name, offset=entry.file_offset, length=entry.file_length)
-
- lst.append(file_entry)
-
- final_map[file_name] = lst
-
- return final_map
-
-def main(argv: List[str]) -> int:
- opts = parse_options(argv[1:])
- if opts.debug:
- print_utils.DEBUG = opts.debug
- print_utils.debug_print(opts)
-
- prefetch_file = open_iorap_prefetch_file(opts.input)
-
- if opts.raw:
- print(prefetch_file)
-
- print_stats_summary(prefetch_file, opts.upper_percent)
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/collector b/startop/scripts/iorap/collector
deleted file mode 100755
index 3dc080a5ac9c..000000000000
--- a/startop/scripts/iorap/collector
+++ /dev/null
@@ -1,403 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APP_STARTUP_DIR="$DIR/../app_startup/"
-source "$DIR/common"
-
-usage() {
- cat <<EOF
-Usage: collector [OPTIONS]...
-
-Runs an application, causes an iorap trace to be collected for it, and then invokes the iorap
-compiler to generate a TraceFile.pb.
-
- -p, --package package of the app to test
- -a, --activity activity of the app to test
- -h, --help usage information (this)
- -v, --verbose enable extra verbose printing
- -i, --inodes path to inodes file (system/extras/pagecache/pagecache.py -d inodes)
- -b, --trace_buffer_size how big to make trace buffer size (default 32768)
- -w, --wait_time how long to run systrace for (default 10) in seconds
- -c, --compiler-filter override the compilation filter if set (default none)
- -o, --output output trace file protobuf (default 'TraceFile.pb')
-EOF
-}
-
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-trace_buffer_size=32768
-wait_time=10
-comp_filter=""
-output_dest="TraceFile.pb"
-
-parse_arguments() {
- while [[ $# -gt 0 ]]; do
- case "$1" in
- -a|--activity)
- activity="$2"
- shift
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -p|--package)
- package="$2"
- shift
- ;;
- -i|--inodes)
- inodes="$2"
- shift
- ;;
- -b|--trace_buffer_size)
- trace_buffer_size="$2"
- shift
- ;;
- -w|--wait_time)
- wait_time="$2"
- shift
- ;;
- -c|--compiler-filter)
- comp_filter="$2"
- shift
- ;;
- -o|--output)
- output_dest="$2"
- shift
- ;;
- -v|--verbose)
- verbose="y"
- ;;
- esac
- shift
- done
-}
-
-remote_pidof() {
- local procname="$1"
- adb shell ps | grep "$procname" | awk '{print $2;}'
-}
-
-remote_pkill() {
- local procname="$1"
- shift
-
- local the_pids=$(remote_pidof "$procname")
- local pid
-
- for pid in $the_pids; do
- verbose_print adb shell kill "$@" "$pid"
- adb shell kill "$@" "$pid"
- done
-}
-
-force_package_compilation() {
- local arg_comp_filter="$1"
- local arg_package="$2"
-
- if [[ $arg_comp_filter == speed-profile ]]; then
- # Force the running app to dump its profiles to disk.
- remote_pkill "$arg_package" -SIGUSR1
- sleep 1 # give some time for above to complete.
- fi
-
- adb shell cmd package compile -m "$arg_comp_filter" -f "$arg_package"
-}
-
-parse_package_dumpsys_line() {
- local what_left="$1"
- local what_right="$2"
- local line="$3"
-
- if [[ $line == *${what_left}*${what_right}* ]]; then
- found="${line#*$what_left}"
- found="${found%$what_right*}"
- echo "$found"
- return 0
- fi
-
- return 1
-}
-
-parse_package_dumpsys_section() {
- local what_left="$1"
- local what_right="$2"
- shift
- local lines="$@"
-
- lines="${lines//$'\n'/}"
-
- local new_lines=()
-
- local current_line=""
- local newline=n
- local line
- for line in "${lines[@]}"; do
- if [[ $line == *: ]]; then
- newline=y
- current_line=""
- new_lines+=("$current_line")
-
- parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0
- else
- # strip all spaces from the start
- line="${line//$' '/}"
- current_line+="$line"
- #prepend to current line
- fi
- done
- [[ "$current_line" != "" ]] && new_lines+=("$current_line")
-
- parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0
-
- return 1
-}
-
-parse_package_compilation() {
- local pkg="$1"
-# [com.google.android.apps.maps]
-
- local compilation_filter
- local is_prebuilt
- local isa
- local etc
-
- local ret_code
-
- read compilation_filter is_prebuilt isa etc <<< "$("$APP_STARTUP_DIR"/query_compiler_filter.py --package "$pkg")"
- ret_code=$?
-
- if [[ $ret_code -eq 0 && x$compilation_filter != x ]]; then
- verbose_print "Package compilation info for $pkg was '$compilation_filter'"
- echo "$compilation_filter"
- return 0
- else
- verbose_print "query failed ret code $ret_code filter=$compilation_filter"
- fi
-
- return $ret_code
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
- usage
- exit 1
-else
- parse_arguments "$@"
-
- # if we do not have have package exit early with an error
- [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1
-
- if [[ -z "$inodes" ]] || ! [[ -f $inodes ]]; then
- echo "--inodes not specified" 1>&2
- exit 1
- fi
-
- if [[ "$activity" == "" ]]; then
- activity="$(get_activity_name "$package")"
- if [[ "$activity" == "" ]]; then
- echo "Activity name could not be found, invalid package name?" 1>&2
- exit 1
- else
- verbose_print "Activity name inferred: " "$activity"
- fi
- fi
-fi
-
-adb root > /dev/null
-
-if [[ "$(adb shell getenforce)" != "Permissive" ]]; then
- adb shell setenforce 0
- adb shell stop
- adb shell start
- adb wait-for-device
-fi
-
-compilation_was="$(parse_package_compilation "$package")"
-if [[ $? -ne 0 ]]; then
- echo "Could not determine package compilation filter; was this package installed?" >&2
- exit 1
-fi
-verbose_print "Package compilation: $compilation_was"
-
-# Cannot downgrade (e.g. from speed-profile to quicken) without forceful recompilation.
-# Forceful recompilation will recompile even if compilation filter was unchanged.
-# Therefore avoid recompiling unless the filter is actually different than what we asked for.
-if [[ "x$comp_filter" != "x" ]] && [[ "$compilation_was" != "$comp_filter" ]]; then
- echo "Current compilation filter is '$compilation_was'; force recompile to '$comp_filter'" >&2
- #TODO: this matching seems hopelessly broken, it will always recompile.
-
- force_package_compilation "$comp_filter" "$package"
-fi
-
-# Drop all caches prior to beginning a systrace, otherwise we won't record anything already in pagecache.
-adb shell "echo 3 > /proc/sys/vm/drop_caches"
-
-trace_tmp_file="$(mktemp -t trace.XXXXXXXXX.html)"
-
-function finish {
- [[ -f "$trace_tmp_file" ]] && rm "$trace_tmp_file"
-}
-trap finish EXIT
-
-launch_application_and_wait_for_trace() {
- local package="$1"
- local activity="$2"
- local timeout=30 # seconds
-
- # Ensure application isn't running already.
- remote_pkill "$package"
-
- # 5 second trace of Home screen causes
- # a trace of the home screen.
- # There is no way to abort the trace
- # so just wait for it to complete instead.
- sleep 30
-
- local time_now="$(logcat_save_timestamp)"
- local retcode=0
-
- verbose_print "Drop caches for non-warm start."
- # Drop all caches to get cold starts.
- adb shell "echo 3 > /proc/sys/vm/drop_caches"
-
- verbose_print "now launching application"
- # Launch an application
- "$APP_STARTUP_DIR"/launch_application "$package" "$activity"
- retcode=$?
- if [[ $retcode -ne 0 ]]; then
- echo "FATAL: Application launch failed." >&2
- return $retcode
- fi
-
- # This blocks until 'am start' returns at which point the application is
- # already to be considered "started" as the first frame has been drawn.
-
- # TODO: check for cold start w.r.t to activitymanager?
-
- # Wait for application to start from the point of view of ActivityTaskManager.
- local pattern="ActivityTaskManager: Displayed $package"
- logcat_wait_for_pattern "$timeout" "$time_now" "$pattern"
- retcode=$?
- if [[ $retcode -ne 0 ]]; then
- echo "FATAL: Could not find '$pattern' in logcat." >&2
- return $retcode
- fi
-
- # Wait for iorapd to finish writing out the perfetto traces for this app.
- iorapd_perfetto_wait_for_app_trace "$package" "$activity" "$timeout" "$time_now"
- retcode=$?
- if [[ $retcode -ne 0 ]]; then
- echo "FATAL: Could not save perfetto app trace file." >&2
- return $retcode
- fi
-
- verbose_print "iorapd has finished collecting app trace file for $package/$activity"
-}
-
-collector_main() {
- # don't even bother trying to run anything until the screen is unlocked.
- "$APP_STARTUP_DIR"/unlock_screen
-
- # Don't mutate state while iorapd is running.
- iorapd_stop || return $?
-
- # Remove all existing metadata for a package/activity in iorapd.
- iorapd_perfetto_purge_app_trace "$package" "$activity" || return $?
- iorapd_compiler_purge_trace_file "$package" "$activity" || return $?
-
- iorapd_perfetto_enable || return $?
- iorapd_readahead_disable || return $?
- iorapd_start || return $?
-
- # Wait for perfetto trace to finished writing itself out.
- launch_application_and_wait_for_trace "$package" "$activity" || return $?
-
- # Pull the perfetto trace for manual inspection.
- iorapd_perfetto_pull_trace_file "$package" "$activity" "perfetto_trace.pb"
-
- # Compile the trace so that the next app run can use prefetching.
- iorapd_compiler_for_app_trace "$package" "$activity" "$inodes" || return $?
-
- # Save TraceFile.pb to local file.
- iorapd_compiler_pull_trace_file "$package" "$activity" "$output_dest" || return $?
- # Remove the TraceFile.pb from the device.
- iorapd_compiler_purge_trace_file "$package" "$activity" || return $?
-
- # TODO: better transactional support for restoring iorapd global properties
- iorapd_perfetto_disable || return $?
-}
-
-collector_main "$@"
-
-verbose_print "Collector finished. Children: "
-if [[ $verbose == y ]]; then
- jobs -p
- ps f -g$$
-fi
-
-exit $?
-
-
-verbose_print "About to begin systrace"
-coproc systrace_fd {
- # Disable stdout buffering since we need to know the output of systrace RIGHT AWAY.
- stdbuf -oL "$ANDROID_BUILD_TOP"/external/chromium-trace/systrace.py --target=android -b "$trace_buffer_size" -t "$wait_time" am pagecache dalvik -o "$trace_tmp_file"
-}
-
-verbose_print "Systrace began"
-
-systrace_pid="$!"
-
-while read -r -u "${systrace_fd[0]}" systrace_output; do
- verbose_print "$systrace_output"
- if [[ "$systrace_output" == *"Starting tracing"* ]]; then
- verbose_print "WE DID SEE STARTING TRACING."
- break
- fi
-done
-# Systrace has begun recording the tracing.
-# Run the application and collect the results.
-
-am_output="$(adb shell am start -S -W "$package"/"$activity")"
-if [[ $? -ne 0 ]]; then
- echo "am start failed" >&2
-
- exit 1
-fi
-
-verbose_print "$am_output"
-total_time="$(echo "$am_output" | grep 'TotalTime:' | sed 's/TotalTime: //g')"
-verbose_print "total time: $total_time"
-
-# Now wait for systrace to finish.
-
-wait "$systrace_pid" || { echo "Systrace finished before am start was finished, try a longer --wait_time"; exit 1; }
-verbose_print "Systrace has now finished"
-verbose_print "$(ls -la "$trace_tmp_file")"
-
-
-iorapd_perfetto_disable
-
-# Now that systrace has finished, convert the trace file html file to a protobuf.
-
-"$ANDROID_BUILD_TOP"/system/iorap/src/py/collector/trace_parser.py -i "$inodes" -t "$trace_tmp_file" -o "$output_dest" || exit 1
-
-echo "Trace file collection complete, trace file saved to \"$output_dest\"!" >&2
-
-finish
diff --git a/startop/scripts/iorap/common b/startop/scripts/iorap/common
deleted file mode 100755
index 387e45d431bd..000000000000
--- a/startop/scripts/iorap/common
+++ /dev/null
@@ -1,253 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
-source "$APP_STARTUP_DIR/lib/common"
-
-IORAPD_DATA_PATH="/data/misc/iorapd"
-
-iorapd_start() {
- verbose_print 'iorapd_start'
- adb shell start iorapd
- sleep 1
- # TODO: block until logcat prints successfully connecting
-}
-
-iorapd_stop() {
- verbose_print 'iorapd_stop'
- adb shell stop iorapd
-}
-
-iorapd_reset() {
- iorapd_stop
- iorapd_start
-}
-
-# Enable perfetto tracing.
-# Subsequent launches of an application will record a perfetto trace protobuf.
-iorapd_perfetto_enable() {
- verbose_print 'enable perfetto'
- adb shell setprop iorapd.perfetto.enable true
- iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Disable perfetto tracing.
-# Subsequent launches of applications will no longer record perfetto trace protobufs.
-iorapd_perfetto_disable() {
- verbose_print 'disable perfetto'
- adb shell setprop iorapd.perfetto.enable false
- iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Enable readahead
-# Subsequent launches of an application will be sped up by iorapd readahead prefetching
-# (Provided an appropriate compiled trace exists for that application)
-iorapd_readahead_enable() {
- if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
- verbose_print 'enable readahead [already enabled]'
- return 0
- fi
- verbose_print 'enable readahead [reset iorapd]'
- adb shell setprop iorapd.readahead.enable true
- iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Disable readahead
-# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
-iorapd_readahead_disable() {
- if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
- verbose_print 'disable readahead [already disabled]'
- return 0
- fi
- verbose_print 'disable readahead [reset iorapd]'
- adb shell setprop iorapd.readahead.enable false
- iorapd_reset # iorapd only reads this flag when initializing
-}
-
-_iorapd_path_to_data_file() {
- local package="$1"
- local activity="$2"
- local suffix="$3"
-
- # Match logic of 'AppComponentName' in iorap::compiler C++ code.
- echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}"
-}
-
-iorapd_perfetto_wait_for_app_trace() {
- local package="$1"
- local activity="$2"
- local timeout="$3"
- local timestamp="$4"
-
- local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
- verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'"
-
- # see event_manager.cc
- local pattern="Perfetto TraceBuffer saved to file: $remote_path"
- logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
-}
-
-# Purge all perfetto traces for a given application.
-iorapd_perfetto_purge_app_trace() {
- local package="$1"
- local activity="$2"
-
- local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
- verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path"
- adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
-}
-
-# Pull the remote perfetto trace file into a local file.
-iorapd_perfetto_pull_trace_file() {
- local package="$1"
- local activity="$2"
- local output_file="$3" # local path
-
- local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
- if ! adb shell "[[ -f '$compiled_path' ]]"; then
- echo "Error: Remote path '$compiled_path' invalid" >&2
- return 1
- fi
- if ! mkdir -p "$(dirname "$output_file")"; then
- echo "Error: Fail to make output directory for '$output_file'" >&2
- return 1
- fi
- verbose_print adb pull "$compiled_path" "$output_file"
- adb pull "$compiled_path" "$output_file"
-}
-
-# Compile a perfetto trace for a given application.
-# This requires the app has run at least once with perfetto tracing enabled.
-iorapd_compiler_for_app_trace() {
- local package="$1"
- local activity="$2"
- local inodes="$3" # local path
-
- # remote path calculations
- local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
- local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")"
- local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
- if ! adb shell "[[ -f '$input_path' ]]"; then
- echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2
- return 1
- fi
-
- if ! [[ -f $inodes ]]; then
- # We could compile using 'diskscan' but it's non-deterministic, so refuse instead.
- echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2
- return 1
- fi
-
- # inodes file needs to be on the device for iorap.cmd.compiler to access it
- local remote_inodes=/data/local/tmp/prefetch/inodes.txt
- adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
- verbose_print adb push "$inodes" "$remote_inodes"
- adb push "$inodes" "$remote_inodes"
-
- verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
- verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
- adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
- retcode=$?
-
- # Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error.
- # TODO: The native compiler code should be handling its own transaction-safety.
- if [[ $retcode -eq 0 ]]; then
- adb shell "mv '$compiled_path' '$compiled_path_final'"
- else
- adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'"
- fi
-
- # Clean up inodes file we just pushed.
-# adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
-
- return $retcode
-}
-
-# Pull the remote compiled trace file into a local file.
-iorapd_compiler_pull_trace_file() {
- local package="$1"
- local activity="$2"
- local output_file="$3" # local path
-
- local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
- if ! adb shell "[[ -f '$compiled_path' ]]"; then
- echo "Error: Remote path '$compiled_path' invalid" >&2
- return 1
- fi
- if ! mkdir -p "$(dirname "$output_file")"; then
- echo "Error: Fail to make output directory for '$output_file'" >&2
- return 1
- fi
- verbose_print adb pull "$compiled_path" "$output_file"
- adb pull "$compiled_path" "$output_file"
-}
-
-# Install a compiled trace file.
-iorapd_compiler_install_trace_file() {
- local package="$1"
- local activity="$2"
- local input_file="$3" # local path
-
- # remote path calculations
- local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
- if ! [[ -f $input_file ]]; then
- echo "Error: File '$input_file' does not exist." >&2
- return 1
- fi
-
- adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1
-
- verbose_print adb push "$input_file" "$compiled_path"
- adb push "$input_file" "$compiled_path"
-}
-
-iorapd_compiler_purge_trace_file() {
- local package="$1"
- local activity="$2"
- local input_file="$3" # local path
-
- local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
- adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
-}
-
-# Blocks until the readahead for the requested package/activity has finished.
-# This assumes that the trace file was already installed, and also that
-# the application launched but not completed yet.
-iorapd_readahead_wait_until_finished() {
- local package="$1"
- local activity="$2"
- local timestamp="$3"
- local timeout="$4"
-
- if [[ $# -lt 4 ]]; then
- echo "FATAL: Expected 4 arguments (actual $# $@)" >&2
- exit 1
- fi
-
- local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
- # See 'read_ahead.cc' LOG(INFO).
- local pattern="Description = $remote_path"
- logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
-}
diff --git a/startop/scripts/iorap/compile_handcrafted_file.py b/startop/scripts/iorap/compile_handcrafted_file.py
deleted file mode 100755
index 6dbbeaf91571..000000000000
--- a/startop/scripts/iorap/compile_handcrafted_file.py
+++ /dev/null
@@ -1,297 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import argparse
-import asyncio
-import csv
-import itertools
-import os
-import re
-import struct
-import sys
-import tempfile
-import time
-import zipfile
-from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union
-
-# Include generated protos.
-dir_name = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(dir_name + "/generated")
-
-from TraceFile_pb2 import *
-
-
-def parse_options(argv: List[str] = None):
- """Parse command line arguments and return an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Compile a TraceFile.proto from a manual text file.")
- # argparse considers args starting with - and -- optional in --help, even though required=True.
- # by using a named argument group --help will clearly say that it's required instead of optional.
- required_named = parser.add_argument_group('required named arguments')
-
- # optional arguments
- # use a group here to get the required arguments to appear 'above' the optional arguments in help.
- optional_named = parser.add_argument_group('optional named arguments')
- optional_named.add_argument('-opb', '--output-proto-binary', dest='output_proto_binary', action='store', help='Write binary proto output to file.')
- optional_named.add_argument('-pm', '--pinlist-meta', dest='pinlist_meta', action='store', help='Path to pinlist.meta (default=none) binary file.')
- optional_named.add_argument('-pmp', '--pinlist-meta-parent', dest='pinlist_meta_parent', action='store', help='Device path that the pinlist.meta applies to (e.g. /data/.../somefile.apk)')
- optional_named.add_argument('-i', '--input', dest='input', action='store', help='Input text file (default stdin).')
- optional_named.add_argument('-zp', '--zip_path', dest='zip_path', action='append', help='Directory containing zip files.')
- optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
- optional_named.add_argument('-ot', '--output-text', dest='output_text', action='store', help='Output text file (default stdout).')
-
- return parser.parse_args(argv)
-
-# TODO: refactor this with a common library file with analyze_metrics.py
-def _debug_print(*args, **kwargs):
- """Print the args to sys.stderr if the --debug/-d flag was passed in."""
- if _debug:
- print(*args, **kwargs, file=sys.stderr)
-
-class BadInputError(Exception):
- pass
-
-InputRecord = NamedTuple('InputRecord', [('filepath', str), ('offset', int), ('length', int), ('remark', str)])
-
-def find_zip_in_paths(original_name, zip_paths):
- # /foo/bar/bax.zip -> bax.zip
- file_basename = os.path.split(original_name)[1]
-
- # the file must be located in one of the --zip-path arguments
- matched = None
- for zip_path in zip_paths:
- for dir_entry in os.listdir(zip_path):
- if dir_entry == file_basename:
- matched = os.path.join(zip_path, dir_entry)
- break
- if matched:
- break
-
- if not matched:
- raise ValueError("%s could not be found in any of the --zip_path specified." %(file_basename))
-
- _debug_print("found zip file ", file_basename, " in ", matched)
-
- if not zipfile.is_zipfile(matched):
- raise ValueError("%s is not a zip file" %(matched))
-
- return matched
-
-def handle_zip_entry(input_record, zip_paths):
-
- res = re.match("([^!]+)[!](.*)", input_record.filepath)
-
- if not res:
- return input_record
-
- # 'foo!bar'
- in_filepath = res[1] # -> 'foo'
- in_zip_entry = res[2] # -> 'bar'
-
- matched = find_zip_in_paths(in_filepath, zip_paths)
-
- zip = zipfile.ZipFile(matched)
-
- try:
- zip_info = zip.getinfo(in_zip_entry)
- except KeyError:
- raise ValueError("%s is not an item in the zip file %s" %(in_zip_entry, matched))
-
- # TODO: do we also need to add header size to this?
- in_offset = zip_info.header_offset
-
- # TODO: if a range is specified, use that instead.
- in_length = zip_info.compress_size
-
- return InputRecord(in_filepath, in_offset, in_length, 'zip entry (%s)' %(in_zip_entry))
-
-def parse_input_file(input: Iterable[str], zip_paths: List[str]) -> Iterable[InputRecord]:
- for line in input:
- line = line.strip()
-
- _debug_print("Line = ", line)
- if not line:
- _debug_print(" skip empty line", line)
- continue
- elif line[0] == "#":
- _debug_print(" skip commented line", line)
- continue
-
- res = re.match("([^\s]+)\s+(\d+)\s+(\d+)", line)
- if not res:
- raise BadInputError("Expected input of form: <str:filepath> <int:offset> <int:length>")
-
- in_filepath = res[1]
- in_offset = int(res[2])
- in_length = int(res[3])
-
- yield handle_zip_entry(InputRecord(in_filepath, in_offset, in_length, 'regular file'), zip_paths)
-
-# format:
-# (<big_endian(i32):file_offset> <big_endian(i32):range_length>)+
-PIN_META_FORMAT = ">ii"
-PIN_META_READ_SIZE = struct.calcsize(PIN_META_FORMAT)
-
-def parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths):
- if not pin_meta_file:
- return ()
-
- global PIN_META_FORMAT
- global PIN_META_READ_SIZE
-
- # '/data/app/com.google.android.GoogleCamera-aNQhzSznf4h_bvJ_MRbweQ==/base.apk'
- # -> 'com.google.android.GoogleCamera'
- package_name_match = re.match('/.*/(.*)-.*=/base.apk', pinlist_meta_parent)
-
- if not package_name_match:
- raise ValueError("%s did not contain the <packagename>.apk" %(pinlist_meta_parent))
-
- package_name = package_name_match[1]
- # "com.google.android.GoogleCamera" -> "GoogleCamera.apk"
- apk_name = package_name.split(".")[-1] + ".apk"
-
- path_to_zip_on_host = find_zip_in_paths(apk_name, zip_paths)
- apk_file_size = os.path.getsize(path_to_zip_on_host)
- _debug_print("APK path '%s' file size '%d'" %(path_to_zip_on_host, apk_file_size))
-
- while True:
- data = pin_meta_file.read(PIN_META_READ_SIZE)
-
- if not data:
- break
-
- (pin_offset, pin_length) = struct.unpack(PIN_META_FORMAT, data) # (offset, length)
-
- remark = 'regular file (pinlist.meta)'
-
- remaining_size = apk_file_size - pin_offset
- if remaining_size < 0:
- print("WARNING: Clamp entry (%d, %d), offset too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
-
- pin_length = pin_length + remaining_size
- pin_offset = pin_offset + remaining_size
-
- if pin_offset < 0:
- pin_offset = 0
-
- remark += '[clamped.offset]'
-
- pin_last_offset = pin_offset + pin_length
- remaining_size = apk_file_size - pin_last_offset
-
- if remaining_size < 0:
- print("WARNING: Clamp entry (%d, %d), length too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
- pin_length = pin_length + remaining_size
-
- remark += '[clamped.length]'
-
- yield InputRecord(pinlist_meta_parent, pin_offset, pin_length, remark)
-
-def write_text_file_output(input_records: Iterable[InputRecord], output_text_file):
- for rec in input_records:
- output_text_file.write("%s %d %d #%s\n" %(rec.filepath, rec.offset, rec.length, rec.remark))
-
-def build_trace_file(input_records: Iterable[InputRecord]) -> TraceFile:
- trace_file = TraceFile()
- trace_file_index = trace_file.index
-
- file_id_counter = 0
- file_id_map = {} # filename -> id
-
- stats_length_total = 0
- filename_stats = {} # filename -> total size
-
- for rec in input_records:
- filename = rec.filepath
-
- file_id = file_id_map.get(filename)
- if not file_id:
- file_id = file_id_counter
- file_id_map[filename] = file_id_counter
- file_id_counter = file_id_counter + 1
-
- file_index_entry = trace_file_index.entries.add()
- file_index_entry.id = file_id
- file_index_entry.file_name = filename
-
- # already in the file index, add the file entry.
- file_entry = trace_file.list.entries.add()
- file_entry.index_id = file_id
- file_entry.file_length = rec.length
- stats_length_total += file_entry.file_length
- file_entry.file_offset = rec.offset
-
- filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
-
- return trace_file
-
-def main():
- global _debug
-
- options= parse_options()
- _debug = options.debug
- _debug_print("parsed options: ", options)
-
- if not options.input:
- input_file = sys.stdin
- _debug_print("input = stdin")
- else:
- input_file = open(options.input)
- _debug_print("input = (file)", options.input)
-
- if not options.output_proto_binary:
- output_proto_file = None
- else:
- output_proto_file = open(options.output_proto_binary, 'wb')
- _debug_print("output_proto_binary = ", output_proto_file)
-
- pinlist_meta_parent = options.pinlist_meta_parent
- if options.pinlist_meta:
- pin_meta_file = open(options.pinlist_meta, 'rb')
- else:
- pin_meta_file = None
-
- if (pinlist_meta_parent == None) != (pin_meta_file == None):
- print("Options must be used together: --pinlist-meta and --pinlist-meta-path")
- return 1
-
- if not options.output_text:
- output_text_file = sys.stdout
- _debug_print("output = stdout")
- else:
- output_text_file = open(options.output_text, 'w')
- _debug_print("output = (file)", options.output_text)
-
- zip_paths = options.zip_path or []
-
- input_records = list(parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths))
- input_records = input_records + list(parse_input_file(input_file, zip_paths))
-
- for p in input_records:
- _debug_print(p)
-
- write_text_file_output(input_records, output_text_file)
- output_text_file.close()
-
- out_proto = build_trace_file(input_records)
-
- if output_proto_file:
- output_proto_file.write(out_proto.SerializeToString())
- output_proto_file.close()
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
deleted file mode 100644
index 1426d34f325d..000000000000
--- a/startop/scripts/iorap/compiler.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import importlib
-import os
-import sys
-import tempfile
-from enum import Enum
-from typing import TextIO, List
-
-# local import
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.print_utils as print_utils
-
-# Type of compiler.
-class CompilerType(Enum):
- HOST = 1 # iorap.cmd.compiler on host
- DEVICE = 2 # adb shell iorap.cmd.compiler
- RI = 3 # compiler.py
-
-def compile_perfetto_trace_ri(
- argv: List[str],
- compiler) -> TextIO:
- print_utils.debug_print('Compile using RI compiler.')
- compiler_trace_file = tempfile.NamedTemporaryFile()
- argv.extend(['-o', compiler_trace_file.name])
- print_utils.debug_print(argv)
- compiler.main([''] + argv)
- return compiler_trace_file
-
-def compile_perfetto_trace_device(inodes_path: str,
- package: str,
- activity: str,
- compiler) -> TextIO:
- print_utils.debug_print('Compile using on-device compiler.')
- compiler_trace_file = tempfile.NamedTemporaryFile()
- compiler.main(inodes_path, package, activity, compiler_trace_file.name)
- return compiler_trace_file
-
-def compile(compiler_type: CompilerType,
- inodes_path: str,
- ri_compiler_argv,
- package: str,
- activity: str) -> TextIO:
- if compiler_type == CompilerType.RI:
- compiler = importlib.import_module('iorap.compiler_ri')
- compiler_trace_file = compile_perfetto_trace_ri(ri_compiler_argv,
- compiler)
- return compiler_trace_file
- if compiler_type == CompilerType.DEVICE:
- compiler = importlib.import_module('iorap.compiler_device')
- compiler_trace_file = compile_perfetto_trace_device(inodes_path,
- package,
- activity,
- compiler)
- return compiler_trace_file
-
- # Should not arrive here.
- raise ValueError('Unknown compiler type')
diff --git a/startop/scripts/iorap/compiler_device.py b/startop/scripts/iorap/compiler_device.py
deleted file mode 100644
index d941cd913fe1..000000000000
--- a/startop/scripts/iorap/compiler_device.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import argparse
-import os
-import sys
-from typing import List
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR)) # framework/base/startop/script
-import lib.print_utils as print_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-from app_startup.lib.app_runner import AppRunner
-
-IORAP_COMMON_BASH_SCRIPT = os.path.join(DIR, 'common')
-
-def parse_options(argv: List[str] = None):
- """Parses command line arguments and returns an argparse Namespace object."""
- parser = argparse.ArgumentParser(description="Compile perfetto trace file")
- required_named = parser.add_argument_group('required named arguments')
-
- required_named.add_argument('-i', dest='inodes', metavar='FILE',
- help='Read cached inode data from a file saved '
- 'earlier with pagecache.py -d')
- required_named.add_argument('-p', dest='package',
- help='Package of the app to be compiled')
-
- optional_named = parser.add_argument_group('optional named arguments')
- optional_named.add_argument('-o', dest='output',
- help='The compiled trace is stored into the output file')
- optional_named.add_argument('-a', dest='activity',
- help='Activity of the app to be compiled')
- optional_named.add_argument('-d', dest='debug', action='store_true'
- , help='Activity of the app to be compiled')
-
- return parser.parse_args(argv)
-
-def main(inodes, package, activity, output, **kwargs) -> int:
- """Entries of the program."""
- if not activity:
- activity = AppRunner.get_activity(package)
-
- passed = iorapd_utils.compile_perfetto_trace_on_device(package, activity,
- inodes)
- if passed and output:
- iorapd_utils.get_iorapd_compiler_trace(package, activity, output)
-
- return 0
-
-if __name__ == '__main__':
- opts = parse_options()
- if opts.debug:
- print_utils.DEBUG = opts.debug
- print_utils.debug_print(opts)
- sys.exit(main(**(vars(opts))))
diff --git a/startop/scripts/iorap/compiler_ri.py b/startop/scripts/iorap/compiler_ri.py
deleted file mode 100755
index 90fc8a8123c5..000000000000
--- a/startop/scripts/iorap/compiler_ri.py
+++ /dev/null
@@ -1,325 +0,0 @@
-#!/usr/bin/env python3
-
-#
-# 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.
-#
-
-#
-# Dependencies:
-#
-# $> sudo apt-get install python3-pip
-# $> pip3 install --user protobuf sqlalchemy sqlite3
-#
-
-import optparse
-import os
-import re
-import sys
-import tempfile
-from pathlib import Path
-from datetime import timedelta
-from typing import Iterable, Optional, List
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-from iorap.generated.TraceFile_pb2 import *
-from iorap.lib.inode2filename import Inode2Filename
-
-parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-sys.path.append(parent_dir_name)
-from trace_analyzer.lib.trace2db import Trace2Db, MmFilemapAddToPageCache, \
- RawFtraceEntry
-import lib.cmd_utils as cmd_utils
-
-_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
-ANDROID_BUILD_TOP = Path(parent_dir_name).parents[3]
-TRACECONV_BIN = ANDROID_BUILD_TOP.joinpath(
- 'external/perfetto/tools/traceconv')
-
-class PageRun:
- """
- Intermediate representation for a run of one or more pages.
- """
- def __init__(self, device_number: int, inode: int, offset: int, length: int):
- self.device_number = device_number
- self.inode = inode
- self.offset = offset
- self.length = length
-
- def __str__(self):
- return "PageRun(device_number=%d, inode=%d, offset=%d, length=%d)" \
- %(self.device_number, self.inode, self.offset, self.length)
-
-def debug_print(msg):
- #print(msg)
- pass
-
-UNDER_LAUNCH = False
-
-def page_cache_entries_to_runs(page_cache_entries: Iterable[MmFilemapAddToPageCache]):
- global _PAGE_SIZE
-
- runs = [
- PageRun(device_number=pg_entry.dev, inode=pg_entry.ino, offset=pg_entry.ofs,
- length=_PAGE_SIZE)
- for pg_entry in page_cache_entries
- ]
-
- for r in runs:
- debug_print(r)
-
- print("Stats: Page runs totaling byte length: %d" %(len(runs) * _PAGE_SIZE))
-
- return runs
-
-def optimize_page_runs(page_runs):
- new_entries = []
- last_entry = None
- for pg_entry in page_runs:
- if last_entry:
- if pg_entry.device_number == last_entry.device_number and pg_entry.inode == last_entry.inode:
- # we are dealing with a run for the same exact file as a previous run.
- if pg_entry.offset == last_entry.offset + last_entry.length:
- # trivially contiguous entries. merge them together.
- last_entry.length += pg_entry.length
- continue
- # Default: Add the run without merging it to a previous run.
- last_entry = pg_entry
- new_entries.append(pg_entry)
- return new_entries
-
-def is_filename_matching_filter(file_name, filters=[]):
- """
- Blacklist-style regular expression filters.
-
- :return: True iff file_name has an RE match in one of the filters.
- """
- for filt in filters:
- res = re.search(filt, file_name)
- if res:
- return True
-
- return False
-
-def build_protobuf(page_runs, inode2filename, filters=[]):
- trace_file = TraceFile()
- trace_file_index = trace_file.index
-
- file_id_counter = 0
- file_id_map = {} # filename -> id
-
- stats_length_total = 0
- filename_stats = {} # filename -> total size
-
- skipped_inode_map = {}
- filtered_entry_map = {} # filename -> count
-
- for pg_entry in page_runs:
- fn = inode2filename.resolve(pg_entry.device_number, pg_entry.inode)
- if not fn:
- skipped_inode_map[pg_entry.inode] = skipped_inode_map.get(pg_entry.inode, 0) + 1
- continue
-
- filename = fn
-
- if filters and not is_filename_matching_filter(filename, filters):
- filtered_entry_map[filename] = filtered_entry_map.get(filename, 0) + 1
- continue
-
- file_id = file_id_map.get(filename)
- # file_id could 0, which satisfies "if file_id" and causes duplicate
- # filename for file id 0.
- if file_id is None:
- file_id = file_id_counter
- file_id_map[filename] = file_id_counter
- file_id_counter = file_id_counter + 1
-
- file_index_entry = trace_file_index.entries.add()
- file_index_entry.id = file_id
- file_index_entry.file_name = filename
-
- # already in the file index, add the file entry.
- file_entry = trace_file.list.entries.add()
- file_entry.index_id = file_id
- file_entry.file_length = pg_entry.length
- stats_length_total += file_entry.file_length
- file_entry.file_offset = pg_entry.offset
-
- filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
-
- for inode, count in skipped_inode_map.items():
- print("WARNING: Skip inode %s because it's not in inode map (%d entries)" %(inode, count))
-
- print("Stats: Sum of lengths %d" %(stats_length_total))
-
- if filters:
- print("Filter: %d total files removed." %(len(filtered_entry_map)))
-
- for fn, count in filtered_entry_map.items():
- print("Filter: File '%s' removed '%d' entries." %(fn, count))
-
- for filename, file_size in filename_stats.items():
- print("%s,%s" %(filename, file_size))
-
- return trace_file
-
-def calc_trace_end_time(trace2db: Trace2Db,
- trace_duration: Optional[timedelta]) -> float:
- """
- Calculates the end time based on the trace duration.
- The start time is the first receiving mm file map event.
- The end time is the start time plus the trace duration.
- All of them are in milliseconds.
- """
- # If the duration is not set, assume all time is acceptable.
- if trace_duration is None:
- # float('inf')
- return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf')
-
- first_event = trace2db.session.query(MmFilemapAddToPageCache).join(
- MmFilemapAddToPageCache.raw_ftrace_entry).order_by(
- RawFtraceEntry.timestamp).first()
-
- # total_seconds() will return a float number.
- return first_event.raw_ftrace_entry.timestamp + trace_duration.total_seconds()
-
-def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[timedelta]):
- end_time = calc_trace_end_time(trace2db, trace_duration)
- # SELECT * FROM tbl ORDER BY id;
- return trace2db.session.query(MmFilemapAddToPageCache).join(
- MmFilemapAddToPageCache.raw_ftrace_entry).filter(
- RawFtraceEntry.timestamp <= end_time).order_by(
- MmFilemapAddToPageCache.id).all()
-
-def transform_perfetto_trace_to_systrace(path_to_perfetto_trace: str,
- path_to_tmp_systrace: str) -> None:
- """ Transforms the systrace file from perfetto trace. """
- cmd_utils.run_command_nofail([str(TRACECONV_BIN),
- 'systrace',
- path_to_perfetto_trace,
- path_to_tmp_systrace])
-
-
-def run(sql_db_path:str,
- trace_file:str,
- trace_duration:Optional[timedelta],
- output_file:str,
- inode_table:str,
- filter:List[str]) -> int:
- trace2db = Trace2Db(sql_db_path)
- # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache.
- trace2db.set_raw_ftrace_entry_filter(\
- lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache')
- # TODO: parse multiple trace files here.
- parse_count = trace2db.parse_file_into_db(trace_file)
-
- mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
- trace_duration)
- print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
-
- page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
- print("DONE. Converted %d entries" %(len(page_runs)))
-
- # TODO: flags to select optimizations.
- optimized_page_runs = optimize_page_runs(page_runs)
- print("DONE. Optimized down to %d entries" %(len(optimized_page_runs)))
-
- print("Build protobuf...")
- trace_file = build_protobuf(optimized_page_runs, inode_table, filter)
-
- print("Write protobuf to file...")
- output_file = open(output_file, 'wb')
- output_file.write(trace_file.SerializeToString())
- output_file.close()
-
- print("DONE")
-
- # TODO: Silent running mode [no output except on error] for build runs.
-
- return 0
-
-def main(argv):
- parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
- parser.add_option('-i', dest='inode_data_file', metavar='FILE',
- help='Read cached inode data from a file saved earlier with pagecache.py -d')
- parser.add_option('-t', dest='trace_file', metavar='FILE',
- help='Path to systrace file (trace.html) that will be parsed')
- parser.add_option('--perfetto-trace', dest='perfetto_trace_file',
- metavar='FILE',
- help='Path to perfetto trace that will be parsed')
-
- parser.add_option('--db', dest='sql_db', metavar='FILE',
- help='Path to intermediate sqlite3 database [default: in-memory].')
-
- parser.add_option('-f', dest='filter', action="append", default=[],
- help="Add file filter. All file entries not matching one of the filters are discarded.")
-
- parser.add_option('-l', dest='launch_lock', action="store_true", default=False,
- help="Exclude all events not inside launch_lock")
-
- parser.add_option('-o', dest='output_file', metavar='FILE',
- help='Output protobuf file')
-
- parser.add_option('--duration', dest='trace_duration', action="store",
- type=int, help='The duration of trace in milliseconds.')
-
- options, categories = parser.parse_args(argv[1:])
-
- # TODO: OptionParser should have some flags to make these mandatory.
- if not options.inode_data_file:
- parser.error("-i is required")
- if not options.trace_file and not options.perfetto_trace_file:
- parser.error("one of -t or --perfetto-trace is required")
- if options.trace_file and options.perfetto_trace_file:
- parser.error("please enter either -t or --perfetto-trace, not both")
- if not options.output_file:
- parser.error("-o is required")
-
- if options.launch_lock:
- print("INFO: Launch lock flag (-l) enabled; filtering all events not inside launch_lock.")
-
- inode_table = Inode2Filename.new_from_filename(options.inode_data_file)
-
- sql_db_path = ":memory:"
- if options.sql_db:
- sql_db_path = options.sql_db
-
- trace_duration = timedelta(milliseconds=options.trace_duration) if \
- options.trace_duration is not None else None
-
- # if the input is systrace
- if options.trace_file:
- return run(sql_db_path,
- options.trace_file,
- trace_duration,
- options.output_file,
- inode_table,
- options.filter)
-
- # if the input is perfetto trace
- # TODO python 3.7 switch to using nullcontext
- with tempfile.NamedTemporaryFile() as trace_file:
- transform_perfetto_trace_to_systrace(options.perfetto_trace_file,
- trace_file.name)
- return run(sql_db_path,
- trace_file.name,
- trace_duration,
- options.output_file,
- inode_table,
- options.filter)
-
-if __name__ == '__main__':
- print(sys.argv)
- sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py
deleted file mode 100644
index b8de70147565..000000000000
--- a/startop/scripts/iorap/compiler_test.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-
-"""
-Unit tests for the compiler.py script.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> pytest compiler_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-import os
-
-import compiler_ri as compiler
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache')
-SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace')
-ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE]
-PERFETTO_TRACE = os.path.join(DIR,
- 'test_fixtures/compiler/common_perfetto_trace.pb')
-
-def assert_compile_result(output, expected, *extra_argv):
- argv = ARGV + ['-o', output] + [args for args in extra_argv]
-
- compiler.main(argv)
-
- with open(output, 'rb') as f1, open(expected, 'rb') as f2:
- assert f1.read() == f2.read()
-
-### Unit tests - testing compiler code directly
-def test_transform_perfetto_trace_to_systrace(tmpdir):
- expected = os.path.join(DIR,
- 'test_fixtures/compiler/test_result_systrace')
- output = tmpdir.mkdir('compiler').join('tmp_systrace')
-
- compiler.transform_perfetto_trace_to_systrace(PERFETTO_TRACE, str(output))
-
- with open(output, 'rb') as f1, open(expected, 'rb') as f2:
- assert f1.read() == f2.read()
-
-### Functional tests - calls 'compiler.py --args...'
-def test_compiler_main(tmpdir):
- output = tmpdir.mkdir('compiler').join('output')
-
- # No duration
- expected = os.path.join(DIR,
- 'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
- assert_compile_result(output, expected)
-
- # 10ms duration
- expected = os.path.join(DIR,
- 'test_fixtures/compiler/test_result_with_duration.TraceFile.pb')
- assert_compile_result(output, expected, '--duration', '10000')
-
- # 30ms duration
- expected = os.path.join(DIR,
- 'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
- assert_compile_result(output, expected, '--duration', '30000')
diff --git a/startop/scripts/iorap/dump_compiled_pb b/startop/scripts/iorap/dump_compiled_pb
deleted file mode 100755
index ad26a7d72c53..000000000000
--- a/startop/scripts/iorap/dump_compiled_pb
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-#
-# Dumps an iorap compiler protobuf from iorap.cmd.compiler into text
-# with gqui.
-#
-
-if [[ "$#" -lt 1 ]]; then
- echo "Usage: $0 <compiler_trace_file.pb> [...args]" >&2
- exit 1
-fi
-
-path_to_proto="$DIR/../../../../../system/iorap/src/serialize/TraceFile.proto"
-
-filename="$1"
-shift
-if ! [[ -f $filename ]]; then
- echo "Error: $filename does not exist." >&2
- exit 1
-fi
-
-gqui "rawproto:$filename" proto "$path_to_proto":iorap.serialize.proto.TraceFile "$@"
diff --git a/startop/scripts/iorap/dump_trace_pb b/startop/scripts/iorap/dump_trace_pb
deleted file mode 100755
index bcec4a524994..000000000000
--- a/startop/scripts/iorap/dump_trace_pb
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-#
-# Dumps a perfetto protobuf collected by iorapd (from perfetto) into text
-# with gqui.
-#
-
-if [[ "$#" -lt 1 ]]; then
- echo "Usage: $0 <perfetto_trace.pb> [...args]" >&2
- exit 1
-fi
-
-path_to_perfetto_proto="$DIR/../../../../../external/perfetto/protos/perfetto/trace/perfetto_trace.proto"
-
-filename="$1"
-shift
-if ! [[ -f $filename ]]; then
- echo "Error: $filename does not exist." >&2
- exit 1
-fi
-
-gqui "rawproto:$filename" proto "$path_to_perfetto_proto":perfetto.protos.Trace "$@"
diff --git a/startop/scripts/iorap/generated/TraceFile_pb2.py b/startop/scripts/iorap/generated/TraceFile_pb2.py
deleted file mode 100644
index f005bed427ca..000000000000
--- a/startop/scripts/iorap/generated/TraceFile_pb2.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: TraceFile.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='TraceFile.proto',
- package='iorap.serialize.proto',
- syntax='proto2',
- serialized_pb=_b('\n\x0fTraceFile.proto\x12\x15iorap.serialize.proto\"u\n\tTraceFile\x12\x34\n\x05index\x18\x01 \x02(\x0b\x32%.iorap.serialize.proto.TraceFileIndex\x12\x32\n\x04list\x18\x02 \x02(\x0b\x32$.iorap.serialize.proto.TraceFileList\"M\n\x0eTraceFileIndex\x12;\n\x07\x65ntries\x18\x01 \x03(\x0b\x32*.iorap.serialize.proto.TraceFileIndexEntry\"4\n\x13TraceFileIndexEntry\x12\n\n\x02id\x18\x01 \x02(\x03\x12\x11\n\tfile_name\x18\x02 \x02(\t\"G\n\rTraceFileList\x12\x36\n\x07\x65ntries\x18\x01 \x03(\x0b\x32%.iorap.serialize.proto.TraceFileEntry\"L\n\x0eTraceFileEntry\x12\x10\n\x08index_id\x18\x01 \x02(\x03\x12\x13\n\x0b\x66ile_offset\x18\x02 \x02(\x03\x12\x13\n\x0b\x66ile_length\x18\x03 \x02(\x03\x42\x1c\n\x18\x63om.google.android.iorapH\x03')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-
-
-
-_TRACEFILE = _descriptor.Descriptor(
- name='TraceFile',
- full_name='iorap.serialize.proto.TraceFile',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='index', full_name='iorap.serialize.proto.TraceFile.index', index=0,
- number=1, type=11, cpp_type=10, label=2,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='list', full_name='iorap.serialize.proto.TraceFile.list', index=1,
- number=2, type=11, cpp_type=10, label=2,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=42,
- serialized_end=159,
-)
-
-
-_TRACEFILEINDEX = _descriptor.Descriptor(
- name='TraceFileIndex',
- full_name='iorap.serialize.proto.TraceFileIndex',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='entries', full_name='iorap.serialize.proto.TraceFileIndex.entries', index=0,
- number=1, type=11, cpp_type=10, label=3,
- has_default_value=False, default_value=[],
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=161,
- serialized_end=238,
-)
-
-
-_TRACEFILEINDEXENTRY = _descriptor.Descriptor(
- name='TraceFileIndexEntry',
- full_name='iorap.serialize.proto.TraceFileIndexEntry',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='id', full_name='iorap.serialize.proto.TraceFileIndexEntry.id', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='file_name', full_name='iorap.serialize.proto.TraceFileIndexEntry.file_name', index=1,
- number=2, type=9, cpp_type=9, label=2,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=240,
- serialized_end=292,
-)
-
-
-_TRACEFILELIST = _descriptor.Descriptor(
- name='TraceFileList',
- full_name='iorap.serialize.proto.TraceFileList',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='entries', full_name='iorap.serialize.proto.TraceFileList.entries', index=0,
- number=1, type=11, cpp_type=10, label=3,
- has_default_value=False, default_value=[],
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=294,
- serialized_end=365,
-)
-
-
-_TRACEFILEENTRY = _descriptor.Descriptor(
- name='TraceFileEntry',
- full_name='iorap.serialize.proto.TraceFileEntry',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='index_id', full_name='iorap.serialize.proto.TraceFileEntry.index_id', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='file_offset', full_name='iorap.serialize.proto.TraceFileEntry.file_offset', index=1,
- number=2, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='file_length', full_name='iorap.serialize.proto.TraceFileEntry.file_length', index=2,
- number=3, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=367,
- serialized_end=443,
-)
-
-_TRACEFILE.fields_by_name['index'].message_type = _TRACEFILEINDEX
-_TRACEFILE.fields_by_name['list'].message_type = _TRACEFILELIST
-_TRACEFILEINDEX.fields_by_name['entries'].message_type = _TRACEFILEINDEXENTRY
-_TRACEFILELIST.fields_by_name['entries'].message_type = _TRACEFILEENTRY
-DESCRIPTOR.message_types_by_name['TraceFile'] = _TRACEFILE
-DESCRIPTOR.message_types_by_name['TraceFileIndex'] = _TRACEFILEINDEX
-DESCRIPTOR.message_types_by_name['TraceFileIndexEntry'] = _TRACEFILEINDEXENTRY
-DESCRIPTOR.message_types_by_name['TraceFileList'] = _TRACEFILELIST
-DESCRIPTOR.message_types_by_name['TraceFileEntry'] = _TRACEFILEENTRY
-
-TraceFile = _reflection.GeneratedProtocolMessageType('TraceFile', (_message.Message,), dict(
- DESCRIPTOR = _TRACEFILE,
- __module__ = 'TraceFile_pb2'
- # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFile)
- ))
-_sym_db.RegisterMessage(TraceFile)
-
-TraceFileIndex = _reflection.GeneratedProtocolMessageType('TraceFileIndex', (_message.Message,), dict(
- DESCRIPTOR = _TRACEFILEINDEX,
- __module__ = 'TraceFile_pb2'
- # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndex)
- ))
-_sym_db.RegisterMessage(TraceFileIndex)
-
-TraceFileIndexEntry = _reflection.GeneratedProtocolMessageType('TraceFileIndexEntry', (_message.Message,), dict(
- DESCRIPTOR = _TRACEFILEINDEXENTRY,
- __module__ = 'TraceFile_pb2'
- # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndexEntry)
- ))
-_sym_db.RegisterMessage(TraceFileIndexEntry)
-
-TraceFileList = _reflection.GeneratedProtocolMessageType('TraceFileList', (_message.Message,), dict(
- DESCRIPTOR = _TRACEFILELIST,
- __module__ = 'TraceFile_pb2'
- # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileList)
- ))
-_sym_db.RegisterMessage(TraceFileList)
-
-TraceFileEntry = _reflection.GeneratedProtocolMessageType('TraceFileEntry', (_message.Message,), dict(
- DESCRIPTOR = _TRACEFILEENTRY,
- __module__ = 'TraceFile_pb2'
- # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileEntry)
- ))
-_sym_db.RegisterMessage(TraceFileEntry)
-
-
-DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.android.iorapH\003'))
-# @@protoc_insertion_point(module_scope)
diff --git a/startop/scripts/iorap/generated/codegen_protos b/startop/scripts/iorap/generated/codegen_protos
deleted file mode 100755
index 5688711ec25d..000000000000
--- a/startop/scripts/iorap/generated/codegen_protos
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APROTOC="$(which aprotoc)"
-
-IORAP_SERIALIZE_DIR="${DIR}/../../../../../../system/iorap/src/serialize"
-IORAP_PROTOS=($IORAP_SERIALIZE_DIR/*.proto)
-
-if [[ $? -ne 0 ]]; then
- echo "Fatal: Missing aprotoc. Set APROTOC=... or lunch build/envsetup.sh?" >&2
- exit 1
-fi
-
-if ! [[ -d $IORAP_SERIALIZE_DIR ]]; then
- echo "Fatal: Directory '$IORAP_SERIALIZE_DIR' does not exist." >&2
- exit 1
-fi
-
-# codegen the .py files into the same directory as this script.
-echo "$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
-"$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
diff --git a/startop/scripts/iorap/lib/inode2filename.py b/startop/scripts/iorap/lib/inode2filename.py
deleted file mode 100644
index 2e713936319a..000000000000
--- a/startop/scripts/iorap/lib/inode2filename.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python3
-
-#
-# 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.
-#
-
-from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union, TextIO
-
-import re
-
-class Inode2Filename:
- """
- Parses a text file of the format
- "uint(dev_t) uint(ino_t) int(file_size) string(filepath)\\n"*
-
- Lines not matching this format are ignored.
- """
-
- def __init__(self, inode_data_file: TextIO):
- """
- Create an Inode2Filename that reads cached inode from a file saved earlier
- (e.g. with pagecache.py -d or with inode2filename --format=textcache)
-
- :param inode_data_file: a file object (e.g. created with open or StringIO).
-
- Lifetime: inode_data_file is only used during the construction of the object.
- """
- self._inode_table = Inode2Filename.build_inode_lookup_table(inode_data_file)
-
- @classmethod
- def new_from_filename(cls, textcache_filename: str) -> 'Inode2Filename':
- """
- Create an Inode2Filename that reads cached inode from a file saved earlier
- (e.g. with pagecache.py -d or with inode2filename --format=textcache)
-
- :param textcache_filename: path to textcache
- """
- with open(textcache_filename) as inode_data_file:
- return cls(inode_data_file)
-
- @staticmethod
- def build_inode_lookup_table(inode_data_file: TextIO) -> Dict[Tuple[int, int], Tuple[str, str]]:
- """
- :return: map { (device_int, inode_int) -> (filename_str, size_str) }
- """
- inode2filename = {}
- for line in inode_data_file:
- # stat -c "%d %i %s %n
- # device number, inode number, total size in bytes, file name
- result = re.match('([0-9]+)d? ([0-9]+) -?([0-9]+) (.*)', line)
- if result:
- inode2filename[(int(result.group(1)), int(result.group(2)))] = \
- (result.group(4), result.group(3))
-
- return inode2filename
-
- def resolve(self, dev_t: int, ino_t: int) -> Optional[str]:
- """
- Return a filename (str) from a (dev_t, ino_t) inode pair.
-
- Returns None if the lookup fails.
- """
- maybe_result = self._inode_table.get((dev_t, ino_t))
-
- if not maybe_result:
- return None
-
- return maybe_result[0] # filename str
-
- def __len__(self) -> int:
- """
- :return: the number of inode entries parsed from the file.
- """
- return len(self._inode_table)
-
- def __repr__(self) -> str:
- """
- :return: string representation for debugging/test failures.
- """
- return "Inode2Filename%s" %(repr(self._inode_table))
-
- # end of class.
diff --git a/startop/scripts/iorap/lib/inode2filename_test.py b/startop/scripts/iorap/lib/inode2filename_test.py
deleted file mode 100755
index 1224c61da641..000000000000
--- a/startop/scripts/iorap/lib/inode2filename_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-
-"""
-Unit tests for inode2filename module.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> ./inode2filename_test.py
- $> pytest inode2filename_test.py
- $> python -m pytest inode2filename_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-from contextlib import contextmanager
-import io
-import shlex
-import sys
-import typing
-
-# pip imports
-import pytest
-
-# local imports
-from inode2filename import *
-
-def create_inode2filename(*contents):
- buf = io.StringIO()
-
- for c in contents:
- buf.write(c)
- buf.write("\n")
-
- buf.seek(0)
-
- i2f = Inode2Filename(buf)
-
- buf.close()
-
- return i2f
-
-def test_inode2filename():
- a = create_inode2filename("")
- assert len(a) == 0
- assert a.resolve(1, 2) == None
-
- a = create_inode2filename("1 2 3 foo.bar")
- assert len(a) == 1
- assert a.resolve(1, 2) == "foo.bar"
- assert a.resolve(4, 5) == None
-
- a = create_inode2filename("1 2 3 foo.bar", "4 5 6 bar.baz")
- assert len(a) == 2
- assert a.resolve(1, 2) == "foo.bar"
- assert a.resolve(4, 5) == "bar.baz"
-
- a = create_inode2filename("1567d 8910 -1 /a/b/c/", "4 5 6 bar.baz")
- assert len(a) == 2
- assert a.resolve(1567, 8910) == "/a/b/c/"
- assert a.resolve(4, 5) == "bar.baz"
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/iorap/lib/iorapd_utils.py b/startop/scripts/iorap/lib/iorapd_utils.py
deleted file mode 100644
index f6f21fd70005..000000000000
--- a/startop/scripts/iorap/lib/iorapd_utils.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Helper util libraries for iorapd related operations."""
-
-import os
-import sys
-
-# up to two level
-sys.path.append(os.path.join(os.path.abspath(__file__),'../..'))
-import lib.cmd_utils as cmd_utils
-
-IORAPID_LIB_DIR = os.path.abspath(os.path.dirname(__file__))
-IORAPD_DATA_PATH = '/data/misc/iorapd'
-IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(IORAPID_LIB_DIR,
- '../common'))
-
-def _iorapd_path_to_data_file(package: str, activity: str, suffix: str) -> str:
- """Gets conventional data filename.
-
- Returns:
- The path of iorapd data file.
-
- """
- # Match logic of 'AppComponentName' in iorap::compiler C++ code.
- return '{}/{}%2F{}.{}'.format(IORAPD_DATA_PATH, package, activity, suffix)
-
-def compile_perfetto_trace_on_device(package: str, activity: str,
- inodes: str) -> bool:
- """Compiles the perfetto trace using on-device compiler."""
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_compiler_for_app_trace',
- [package, activity, inodes])
- return passed
-
-def get_iorapd_compiler_trace(package: str, activity: str, dest: str) -> str:
- """Gets compiler trace to dest file."""
- src = _iorapd_path_to_data_file(package, activity, 'compiled_trace.pb')
- passed, _ = cmd_utils.run_shell_command('adb pull "{}" "{}"'.format(src, dest))
- if not passed:
- return False
- return True
-
-def iorapd_compiler_install_trace_file(package: str, activity: str,
- input_file: str) -> bool:
- """Installs a compiled trace file.
-
- Returns:
- Whether the trace file is installed successful or not.
- """
- # remote path calculations
- compiled_path = _iorapd_path_to_data_file(package, activity,
- 'compiled_trace.pb')
-
- if not os.path.exists(input_file):
- print('Error: File {} does not exist'.format(input_file))
- return False
-
- passed, _ = cmd_utils.run_adb_shell_command(
- 'mkdir -p "$(dirname "{}")"'.format(compiled_path))
- if not passed:
- return False
-
- passed, _ = cmd_utils.run_shell_command('adb push "{}" "{}"'.format(
- input_file, compiled_path))
-
- return passed
-
-def wait_for_iorapd_finish(package: str,
- activity: str,
- timeout: int,
- debug: bool,
- logcat_timestamp: str)->bool:
- """Waits for the finish of iorapd.
-
- Returns:
- A bool indicates whether the iorapd is done successfully or not.
- """
- # Set verbose for bash script based on debug flag.
- if debug:
- os.putenv('verbose', 'y')
-
- # Validate that readahead completes.
- # If this fails for some reason, then this will also discard the timing of
- # the run.
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_readahead_wait_until_finished',
- [package, activity, logcat_timestamp,
- str(timeout)])
- return passed
-
-
-def enable_iorapd_readahead() -> bool:
- """
- Disable readahead. Subsequent launches of an application will be sped up
- by iorapd readahead prefetching.
-
- Returns:
- A bool indicates whether the enabling is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_readahead_enable', [])
- return passed
-
-def disable_iorapd_readahead() -> bool:
- """
- Disable readahead. Subsequent launches of an application will be not be sped
- up by iorapd readahead prefetching.
-
- Returns:
- A bool indicates whether the disabling is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_readahead_disable', [])
- return passed
-
-def enable_iorapd_perfetto() -> bool:
- """
- Enable Perfetto. Subsequent launches of an application will record a perfetto
- trace protobuf.
-
- Returns:
- A bool indicates whether the enabling is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_perfetto_enable', [])
- return passed
-
-def disable_iorapd_perfetto() -> bool:
- """
- Disable Perfetto. Subsequent launches of applications will no longer record
- perfetto trace protobufs.
-
- Returns:
- A bool indicates whether the disabling is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_perfetto_disable', [])
- return passed
-
-def start_iorapd() -> bool:
- """
- Starts iorapd.
-
- Returns:
- A bool indicates whether the starting is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_start', [])
- return passed
-
-def stop_iorapd() -> bool:
- """
- Stops iorapd.
-
- Returns:
- A bool indicates whether the stopping is done successfully or not.
- """
- passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
- 'iorapd_stop', [])
- return passed
-
diff --git a/startop/scripts/iorap/pull_textcache b/startop/scripts/iorap/pull_textcache
deleted file mode 100755
index 05544263957d..000000000000
--- a/startop/scripts/iorap/pull_textcache
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-if [[ $# -lt 1 ]]; then
- echo "Usage: $0 <output-filename>" >&2
- exit 1
-fi
-
-# see compiler/main.cc for list of roots
-adb shell iorap.inode2filename --output-format=textcache --output=/data/local/tmp/dumpcache --all --root=/system --root=/apex --root=/vendor --root=/data --root=/product --root=/metadata
-adb pull /data/local/tmp/dumpcache "$1"
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb b/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
deleted file mode 100644
index a47ad3d5d9ec..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_systrace b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
deleted file mode 100644
index 4573738db5c6..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_systrace
+++ /dev/null
@@ -1,5 +0,0 @@
-<...>-2965 (-----) [001] .... 10000.746629: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000679ee1ec pfn=1299913 ofs=192512
-<...>-2965 (-----) [001] .... 10010.746664: mm_filemap_add_to_page_cache: dev 253:6 ino 2 page=0000000006cd2fb7 pfn=1296251 ofs=196608
-<...>-2965 (-----) [001] .... 10020.746677: mm_filemap_add_to_page_cache: dev 253:6 ino 3 page=00000000af82f3d6 pfn=1419330 ofs=200704
-<...>-2965 (-----) [001] .... 10030.746693: mm_filemap_add_to_page_cache: dev 253:6 ino 4 page=000000002840f054 pfn=1304928 ofs=204800
-<...>-2965 (-----) [001] .... 10040.746706: mm_filemap_add_to_page_cache: dev 253:6 ino 5 page=000000004a59da17 pfn=1288069 ofs=208896
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_textcache b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
deleted file mode 100644
index da03004ec6fb..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_textcache
+++ /dev/null
@@ -1,2 +0,0 @@
-64774 1 -1 /system/test1
-64774 3 -1 /data/test2
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace b/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
deleted file mode 100644
index 59ff7537180b..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
+++ /dev/null
@@ -1,748 +0,0 @@
-TRACE:
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 30624/30624 #P:4
-#
-# _-----=> irqs-off
-# / _----=> need-resched
-# | / _---=> hardirq/softirq
-# || / _--=> preempt-depth
-# ||| / delay
-# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION
-# | | | | |||| | |
- <unknown>-27388 (-----) [004] .... 1920260.530929: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1461937 ofs=9535488
- <unknown>-27388 (-----) [005] .... 1920260.532161: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1344589 ofs=9474048
- <unknown>-27388 (-----) [005] .... 1920260.532183: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1153671 ofs=9478144
- <unknown>-27388 (-----) [005] .... 1920260.532184: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1219563 ofs=9482240
- <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1083162 ofs=9486336
- <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1147318 ofs=9490432
- <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1333594 ofs=9494528
- <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1375715 ofs=9498624
- <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1184831 ofs=9502720
- <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1241653 ofs=9506816
- <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1134975 ofs=9510912
- <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1145772 ofs=9515008
- <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1090457 ofs=9519104
- <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1137942 ofs=9523200
- <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1130123 ofs=9527296
- <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1208783 ofs=9531392
- <unknown>-27388 (-----) [005] .... 1920260.532192: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1294989 ofs=9539584
- <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1163979 ofs=9543680
- <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1350628 ofs=9547776
- <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1386717 ofs=9551872
- <unknown>-27388 (-----) [005] .... 1920260.532207: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316148 ofs=9555968
- <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316419 ofs=9560064
- <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1149076 ofs=9564160
- <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1372772 ofs=9568256
- <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1116389 ofs=9572352
- <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1325458 ofs=9576448
- <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1195423 ofs=9580544
- <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1250964 ofs=9584640
- <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1196027 ofs=9588736
- <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1354059 ofs=9592832
- <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1264649 ofs=9596928
- <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1245285 ofs=9601024
- <unknown>-27388 (-----) [005] .... 1920260.535119: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1411552 ofs=44244992
- <unknown>-27388 (-----) [005] .... 1920260.535129: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1483081 ofs=433524736
- <unknown>-27388 (-----) [004] .... 1920260.536144: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1276173 ofs=438185984
- <unknown>-27388 (-----) [004] .... 1920260.536462: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1174575 ofs=44249088
- <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1126294 ofs=44253184
- <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1248232 ofs=44257280
- <unknown>-27388 (-----) [004] .... 1920260.537065: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1332993 ofs=44240896
- <unknown>-27388 (-----) [006] .... 1920260.537646: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1153343 ofs=44400640
- <unknown>-27388 (-----) [005] .... 1920260.538777: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1358397 ofs=44474368
- <unknown>-12683 (-----) [006] .... 1920260.560094: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1426577 ofs=0
- <unknown>-12683 (-----) [006] .... 1920260.560105: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117587 ofs=1171456
- <unknown>-12683 (-----) [006] .... 1920260.561199: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099987 ofs=4096
- <unknown>-12683 (-----) [006] .... 1920260.561411: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099910 ofs=16384
- <unknown>-12683 (-----) [006] .... 1920260.561598: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099905 ofs=20480
- <unknown>-12683 (-----) [006] .... 1920260.561758: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099883 ofs=32768
- <unknown>-12683 (-----) [006] .... 1920260.562088: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099809 ofs=36864
- <unknown>-12683 (-----) [006] .... 1920260.562325: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099803 ofs=98304
- <unknown>-12683 (-----) [006] .... 1920260.562516: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099795 ofs=102400
- <unknown>-12683 (-----) [006] .... 1920260.563094: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1107649 ofs=12288
- <unknown>-12683 (-----) [006] .... 1920260.563105: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1269029 ofs=16384
- <unknown>-12683 (-----) [006] .... 1920260.563785: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1451096 ofs=8192
- <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1301480 ofs=12288
- <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1314353 ofs=16384
- <unknown>-12683 (-----) [006] .... 1920260.563791: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1216744 ofs=24576
- <unknown>-12683 (-----) [006] .... 1920260.564309: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099787 ofs=49152
- <unknown>-12683 (-----) [006] .... 1920260.564514: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099778 ofs=53248
- <unknown>-12683 (-----) [005] .... 1920260.564756: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1148849 ofs=114688
- <unknown>-12683 (-----) [005] .... 1920260.564973: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1164731 ofs=118784
- <unknown>-12683 (-----) [005] .... 1920260.565000: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1170255 ofs=0
- <unknown>-12683 (-----) [005] .... 1920260.565003: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1181043 ofs=4096
- <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1296004 ofs=8192
- <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1102004 ofs=12288
- <unknown>-12683 (-----) [005] .... 1920260.565626: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1351232 ofs=470597632
- <unknown>-12683 (-----) [005] .... 1920260.565982: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1391336 ofs=40210432
- <unknown>-12683 (-----) [005] .... 1920260.565985: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267536 ofs=12668928
- <unknown>-27388 (-----) [007] .... 1920260.566082: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1256752 ofs=43921408
- <unknown>-12683 (-----) [005] .... 1920260.566516: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1110966 ofs=176226304
- <unknown>-12683 (-----) [005] .... 1920260.566519: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1060586 ofs=12967936
- <unknown>-12683 (-----) [004] .... 1920260.567773: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117234 ofs=421888
- <unknown>-12683 (-----) [005] .... 1920260.568604: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1210571 ofs=430080
- <unknown>-12683 (-----) [005] .... 1920260.568887: mm_filemap_add_to_page_cache: dev 0:64771 ino 69 page=0000000000000000 pfn=1055640 ofs=0
- <unknown>-12683 (-----) [005] .... 1920260.568908: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1142694 ofs=0
- <unknown>-12683 (-----) [005] .... 1920260.568910: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1060788 ofs=299008
- <unknown>-12683 (-----) [005] .... 1920260.569418: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1085046 ofs=4096
- <unknown>-12683 (-----) [005] .... 1920260.569640: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1057135 ofs=8192
- <unknown>-12683 (-----) [005] .... 1920260.569833: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1058976 ofs=19406848
- <unknown>-12683 (-----) [005] .... 1920260.569835: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1477947 ofs=10526720
- <unknown>-12683 (-----) [005] .... 1920260.572285: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1237492 ofs=299008
- <unknown>-12683 (-----) [005] .... 1920260.572297: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1264914 ofs=339968
- <unknown>-12683 (-----) [005] .... 1920260.572314: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1434748 ofs=348160
- <unknown>-12683 (-----) [005] .... 1920260.572316: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1372959 ofs=352256
- <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1258955 ofs=356352
- <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1113420 ofs=360448
- <unknown>-12683 (-----) [005] .... 1920260.572318: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1137083 ofs=364544
- <unknown>-12683 (-----) [004] .... 1920260.575490: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1379679 ofs=65536
- <unknown>-12683 (-----) [006] .... 1920260.576194: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1323898 ofs=69632
- <unknown>-12683 (-----) [006] .... 1920260.576248: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323895 ofs=262623232
- <unknown>-12683 (-----) [006] .... 1920260.576251: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323861 ofs=13156352
- <unknown>-12683 (-----) [005] .... 1920260.576810: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1477585 ofs=262590464
- <unknown>-12683 (-----) [004] .... 1920260.577197: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1267617 ofs=25206784
- <unknown>-12683 (-----) [004] .... 1920260.577200: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267618 ofs=12636160
- <unknown>-12683 (-----) [005] .... 1920260.577725: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1056225 ofs=228618240
- <unknown>-12683 (-----) [005] .... 1920260.577727: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1164942 ofs=13082624
- <unknown>-12683 (-----) [007] .... 1920260.578411: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372616 ofs=0
- <unknown>-12683 (-----) [007] .... 1920260.578422: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307468 ofs=4096
- <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1120117 ofs=8192
- <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1217989 ofs=12288
- <unknown>-12683 (-----) [007] .... 1920260.578650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475011 ofs=5419008
- <unknown>-12683 (-----) [007] .... 1920260.578653: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1066084 ofs=236453888
- <unknown>-12683 (-----) [007] .... 1920260.578654: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1100271 ofs=13099008
- <unknown>-12683 (-----) [004] .... 1920260.579004: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1485156 ofs=5423104
- <unknown>-12683 (-----) [004] .... 1920260.579005: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1124212 ofs=5427200
- <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1195377 ofs=5431296
- <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1265888 ofs=5435392
- <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1170194 ofs=5439488
- <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1403742 ofs=5443584
- <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1123826 ofs=5447680
- <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255034 ofs=5451776
- <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1190447 ofs=5455872
- <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286864 ofs=5459968
- <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1428535 ofs=5464064
- <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1184092 ofs=5468160
- <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1411906 ofs=5472256
- <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1342349 ofs=5476352
- <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1188185 ofs=5480448
- <unknown>-12683 (-----) [004] .... 1920260.579014: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1158702 ofs=5484544
- <unknown>-12683 (-----) [005] .... 1920260.579430: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1299421 ofs=5230592
- <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1317097 ofs=5234688
- <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1441714 ofs=5238784
- <unknown>-12683 (-----) [005] .... 1920260.579438: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1081974 ofs=5242880
- <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1128684 ofs=5246976
- <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447381 ofs=5251072
- <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1466410 ofs=5255168
- <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1259909 ofs=5259264
- <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1125784 ofs=5263360
- <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1270592 ofs=5267456
- <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246070 ofs=5271552
- <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472544 ofs=5275648
- <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1113357 ofs=5279744
- <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1202021 ofs=5283840
- <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078639 ofs=5287936
- <unknown>-12683 (-----) [005] .... 1920260.579449: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1176171 ofs=5292032
- <unknown>-12683 (-----) [005] .... 1920260.579450: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1089516 ofs=5296128
- <unknown>-12683 (-----) [005] .... 1920260.579451: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1400065 ofs=5300224
- <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300489 ofs=5304320
- <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452081 ofs=5308416
- <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161862 ofs=5312512
- <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161871 ofs=5316608
- <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263798 ofs=5320704
- <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1126887 ofs=5324800
- <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1375498 ofs=5328896
- <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328067 ofs=5332992
- <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1420691 ofs=5337088
- <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1298707 ofs=5341184
- <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078670 ofs=5345280
- <unknown>-12683 (-----) [005] .... 1920260.579457: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1430498 ofs=5349376
- <unknown>-12683 (-----) [005] .... 1920260.579458: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1338720 ofs=5353472
- <unknown>-12683 (-----) [005] .... 1920260.579476: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452611 ofs=5357568
- <unknown>-12683 (-----) [006] .... 1920260.580451: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241967 ofs=0
- <unknown>-12683 (-----) [006] .... 1920260.580454: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1116541 ofs=4096
- <unknown>-12683 (-----) [006] .... 1920260.580461: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1145049 ofs=8192
- <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1277255 ofs=12288
- <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098037 ofs=16384
- <unknown>-12683 (-----) [006] .... 1920260.580463: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135986 ofs=20480
- <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154455 ofs=24576
- <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1221822 ofs=28672
- <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1078684 ofs=32768
- <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1158876 ofs=36864
- <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289644 ofs=40960
- <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289386 ofs=45056
- <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1131002 ofs=49152
- <unknown>-12683 (-----) [006] .... 1920260.580467: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1464335 ofs=53248
- <unknown>-12683 (-----) [006] .... 1920260.580468: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135789 ofs=57344
- <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1240897 ofs=61440
- <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241770 ofs=65536
- <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1421959 ofs=69632
- <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230007 ofs=73728
- <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1109271 ofs=77824
- <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159974 ofs=81920
- <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154528 ofs=86016
- <unknown>-12683 (-----) [006] .... 1920260.580472: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1315790 ofs=90112
- <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1185583 ofs=94208
- <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1253153 ofs=98304
- <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103982 ofs=102400
- <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1284589 ofs=106496
- <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1169601 ofs=110592
- <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206248 ofs=114688
- <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1261161 ofs=118784
- <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1305841 ofs=122880
- <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1468293 ofs=126976
- <unknown>-12683 (-----) [004] .... 1920260.580646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318816 ofs=16384
- <unknown>-12683 (-----) [004] .... 1920260.580649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472922 ofs=20480
- <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1473229 ofs=24576
- <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1524262 ofs=28672
- <unknown>-12683 (-----) [004] .... 1920260.580656: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1205714 ofs=32768
- <unknown>-12683 (-----) [004] .... 1920260.580657: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310560 ofs=36864
- <unknown>-12683 (-----) [004] .... 1920260.580658: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1295070 ofs=40960
- <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1404093 ofs=45056
- <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435814 ofs=49152
- <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435442 ofs=53248
- <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1096077 ofs=57344
- <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1483793 ofs=61440
- <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1231298 ofs=65536
- <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1215648 ofs=69632
- <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327326 ofs=73728
- <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1108894 ofs=77824
- <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327545 ofs=81920
- <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328804 ofs=86016
- <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300171 ofs=90112
- <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353250 ofs=94208
- <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1333681 ofs=98304
- <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1144969 ofs=102400
- <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1450962 ofs=106496
- <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255701 ofs=110592
- <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294782 ofs=114688
- <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1226912 ofs=118784
- <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294579 ofs=122880
- <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246960 ofs=126976
- <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1199086 ofs=131072
- <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1449590 ofs=135168
- <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1276363 ofs=139264
- <unknown>-12683 (-----) [004] .... 1920260.580675: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1389998 ofs=143360
- <unknown>-12683 (-----) [004] .... 1920260.580739: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1423031 ofs=1249280
- <unknown>-12683 (-----) [004] .... 1920260.580741: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1171032 ofs=1253376
- <unknown>-12683 (-----) [004] .... 1920260.580742: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1320946 ofs=1257472
- <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314696 ofs=1261568
- <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1414864 ofs=1265664
- <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1334933 ofs=1269760
- <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242845 ofs=1273856
- <unknown>-12683 (-----) [004] .... 1920260.580747: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289488 ofs=1277952
- <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1335445 ofs=1282048
- <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289663 ofs=1286144
- <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1080462 ofs=1290240
- <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286303 ofs=1294336
- <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353531 ofs=1298432
- <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1280701 ofs=1302528
- <unknown>-12683 (-----) [004] .... 1920260.580751: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1107730 ofs=1306624
- <unknown>-12683 (-----) [004] .... 1920260.580752: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242729 ofs=1310720
- <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078336 ofs=1314816
- <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372425 ofs=1318912
- <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1248813 ofs=1323008
- <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1201155 ofs=1327104
- <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1250103 ofs=1331200
- <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1359710 ofs=1335296
- <unknown>-12683 (-----) [004] .... 1920260.580756: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1272462 ofs=1339392
- <unknown>-12683 (-----) [004] .... 1920260.580758: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1097035 ofs=1343488
- <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1233124 ofs=1347584
- <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1455812 ofs=1351680
- <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355689 ofs=1355776
- <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263593 ofs=1359872
- <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1230789 ofs=1363968
- <unknown>-12683 (-----) [004] .... 1920260.580761: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1143766 ofs=1368064
- <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1269666 ofs=1372160
- <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353022 ofs=1376256
- <unknown>-12683 (-----) [004] .... 1920260.581613: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355509 ofs=258048
- <unknown>-12683 (-----) [004] .... 1920260.581615: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1178902 ofs=262144
- <unknown>-12683 (-----) [004] .... 1920260.581616: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193649 ofs=266240
- <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1225497 ofs=270336
- <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1228259 ofs=274432
- <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1309674 ofs=278528
- <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1239390 ofs=282624
- <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1468083 ofs=286720
- <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1292751 ofs=290816
- <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318066 ofs=294912
- <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1489314 ofs=299008
- <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1169867 ofs=303104
- <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314256 ofs=307200
- <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310230 ofs=311296
- <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1356180 ofs=315392
- <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1419179 ofs=319488
- <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307265 ofs=323584
- <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1218590 ofs=327680
- <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447586 ofs=331776
- <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1209382 ofs=335872
- <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1072148 ofs=339968
- <unknown>-12683 (-----) [004] .... 1920260.581645: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1227195 ofs=344064
- <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246369 ofs=348160
- <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193845 ofs=352256
- <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1137553 ofs=356352
- <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475215 ofs=360448
- <unknown>-12683 (-----) [004] .... 1920260.581648: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1258935 ofs=364544
- <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1448788 ofs=368640
- <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447611 ofs=372736
- <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1290842 ofs=376832
- <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447826 ofs=380928
- <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1181016 ofs=385024
- <unknown>-12683 (-----) [005] .... 1920260.582230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216810 ofs=1662976
- <unknown>-12683 (-----) [005] .... 1920260.582234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1175966 ofs=1667072
- <unknown>-12683 (-----) [005] .... 1920260.582235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1449798 ofs=1671168
- <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1273480 ofs=1675264
- <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1152779 ofs=1679360
- <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1272810 ofs=1683456
- <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1248634 ofs=1687552
- <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1203376 ofs=1691648
- <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1138880 ofs=1695744
- <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1344591 ofs=1699840
- <unknown>-12683 (-----) [005] .... 1920260.582239: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416060 ofs=1703936
- <unknown>-12683 (-----) [005] .... 1920260.582246: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1128676 ofs=1708032
- <unknown>-12683 (-----) [005] .... 1920260.582247: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1301921 ofs=1712128
- <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1384569 ofs=1716224
- <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1249106 ofs=1720320
- <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206596 ofs=1724416
- <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1429831 ofs=1728512
- <unknown>-12683 (-----) [005] .... 1920260.582252: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1107796 ofs=1732608
- <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098336 ofs=1736704
- <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230286 ofs=1740800
- <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1100370 ofs=1744896
- <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241930 ofs=1748992
- <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1366807 ofs=1753088
- <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1136252 ofs=1757184
- <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1274291 ofs=1761280
- <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1254775 ofs=1765376
- <unknown>-12683 (-----) [005] .... 1920260.582259: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1194679 ofs=1769472
- <unknown>-12683 (-----) [005] .... 1920260.582262: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1177090 ofs=1773568
- <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1343925 ofs=1777664
- <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159217 ofs=1781760
- <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435471 ofs=1785856
- <unknown>-12683 (-----) [005] .... 1920260.582264: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435529 ofs=1789952
- <unknown>-12683 (-----) [004] .... 1920260.582524: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1181910 ofs=0
- <unknown>-12683 (-----) [004] .... 1920260.582528: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1212021 ofs=4096
- <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1162778 ofs=8192
- <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1107700 ofs=12288
- <unknown>-12683 (-----) [004] .... 1920260.583553: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1093394 ofs=3399680
- <unknown>-12683 (-----) [004] .... 1920260.583984: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1121431 ofs=242503680
- <unknown>-12683 (-----) [004] .... 1920260.583986: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1168551 ofs=13115392
- <unknown>-12683 (-----) [004] .... 1920260.584304: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347409 ofs=0
- <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1428681 ofs=4096
- <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1259106 ofs=8192
- <unknown>-12683 (-----) [004] .... 1920260.584308: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343229 ofs=12288
- <unknown>-12694 (-----) [005] .... 1920260.584622: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1098733 ofs=1531904
- <unknown>-12696 (-----) [006] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331319 ofs=1536000
- <unknown>-12694 (-----) [005] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278537 ofs=1540096
- <unknown>-12696 (-----) [006] .... 1920260.584631: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492534 ofs=1544192
- <unknown>-12694 (-----) [005] .... 1920260.584636: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1460878 ofs=1548288
- <unknown>-12694 (-----) [005] .... 1920260.584640: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092973 ofs=1552384
- <unknown>-12694 (-----) [005] .... 1920260.584641: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103200 ofs=1556480
- <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257426 ofs=1560576
- <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1219424 ofs=1564672
- <unknown>-12683 (-----) [004] .... 1920260.584660: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279352 ofs=1568768
- <unknown>-12696 (-----) [006] .... 1920260.584662: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260572 ofs=1572864
- <unknown>-12683 (-----) [004] .... 1920260.584663: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225809 ofs=1576960
- <unknown>-12696 (-----) [006] .... 1920260.584665: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1350766 ofs=1585152
- <unknown>-12697 (-----) [007] .... 1920260.584666: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1107173 ofs=1581056
- <unknown>-12683 (-----) [004] .... 1920260.584668: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305885 ofs=1589248
- <unknown>-12694 (-----) [005] .... 1920260.584669: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293385 ofs=1593344
- <unknown>-12696 (-----) [006] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1173841 ofs=1597440
- <unknown>-12697 (-----) [007] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080021 ofs=1601536
- <unknown>-12683 (-----) [004] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1147419 ofs=1605632
- <unknown>-12696 (-----) [006] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1252762 ofs=1609728
- <unknown>-12694 (-----) [005] .... 1920260.584674: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1323916 ofs=1613824
- <unknown>-12683 (-----) [004] .... 1920260.584675: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155631 ofs=1617920
- <unknown>-12696 (-----) [006] .... 1920260.584676: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449815 ofs=1622016
- <unknown>-12694 (-----) [005] .... 1920260.584678: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227069 ofs=1626112
- <unknown>-12696 (-----) [006] .... 1920260.584680: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317692 ofs=1630208
- <unknown>-12694 (-----) [005] .... 1920260.584681: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492244 ofs=1634304
- <unknown>-12683 (-----) [004] .... 1920260.584682: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241876 ofs=1638400
- <unknown>-12697 (-----) [007] .... 1920260.585446: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1402958 ofs=167936
- <unknown>-12697 (-----) [007] .... 1920260.585449: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133263 ofs=172032
- <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1295502 ofs=176128
- <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1249495 ofs=180224
- <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237999 ofs=184320
- <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280965 ofs=188416
- <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1208361 ofs=192512
- <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308840 ofs=196608
- <unknown>-12695 (-----) [004] .... 1920260.585455: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138875 ofs=569344
- <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314886 ofs=573440
- <unknown>-12697 (-----) [007] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242734 ofs=200704
- <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447386 ofs=577536
- <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241302 ofs=204800
- <unknown>-12695 (-----) [004] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328663 ofs=581632
- <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1476101 ofs=208896
- <unknown>-12695 (-----) [004] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209461 ofs=585728
- <unknown>-12697 (-----) [007] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080147 ofs=212992
- <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128509 ofs=217088
- <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371915 ofs=221184
- <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1264015 ofs=225280
- <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1211695 ofs=229376
- <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1150386 ofs=233472
- <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1135747 ofs=237568
- <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128230 ofs=241664
- <unknown>-12697 (-----) [007] .... 1920260.585464: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155451 ofs=245760
- <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246841 ofs=249856
- <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1462971 ofs=253952
- <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131333 ofs=258048
- <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289407 ofs=262144
- <unknown>-12695 (-----) [004] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1134730 ofs=589824
- <unknown>-12697 (-----) [007] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289873 ofs=266240
- <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448734 ofs=270336
- <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129776 ofs=593920
- <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524090 ofs=274432
- <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399725 ofs=598016
- <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524081 ofs=278528
- <unknown>-12695 (-----) [004] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1276535 ofs=602112
- <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524060 ofs=282624
- <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449847 ofs=606208
- <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158944 ofs=286720
- <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384536 ofs=610304
- <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116785 ofs=290816
- <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308118 ofs=614400
- <unknown>-12697 (-----) [007] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448669 ofs=294912
- <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227050 ofs=618496
- <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289324 ofs=622592
- <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1187869 ofs=626688
- <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1400523 ofs=630784
- <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1344176 ofs=634880
- <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092871 ofs=638976
- <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092021 ofs=643072
- <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1198169 ofs=647168
- <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371540 ofs=651264
- <unknown>-12683 (-----) [005] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195003 ofs=348160
- <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228787 ofs=655360
- <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236123 ofs=659456
- <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137213 ofs=663552
- <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1294618 ofs=667648
- <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241048 ofs=671744
- <unknown>-12695 (-----) [004] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228779 ofs=675840
- <unknown>-12683 (-----) [005] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199292 ofs=352256
- <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200861 ofs=356352
- <unknown>-12695 (-----) [004] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1309572 ofs=679936
- <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215770 ofs=360448
- <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1409002 ofs=684032
- <unknown>-12683 (-----) [005] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151883 ofs=364544
- <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103729 ofs=688128
- <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468126 ofs=368640
- <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162720 ofs=692224
- <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1251672 ofs=372736
- <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199221 ofs=696320
- <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1283325 ofs=376832
- <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1190489 ofs=380928
- <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489117 ofs=385024
- <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1273899 ofs=389120
- <unknown>-12683 (-----) [005] .... 1920260.585485: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1274459 ofs=393216
- <unknown>-12683 (-----) [005] .... 1920260.585486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1316649 ofs=397312
- <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1375678 ofs=401408
- <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1483317 ofs=405504
- <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1240286 ofs=409600
- <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131345 ofs=413696
- <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200483 ofs=417792
- <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384693 ofs=421888
- <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161385 ofs=425984
- <unknown>-12683 (-----) [005] .... 1920260.585494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452025 ofs=430080
- <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1253654 ofs=434176
- <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116697 ofs=438272
- <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1432645 ofs=442368
- <unknown>-12694 (-----) [006] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337397 ofs=16384
- <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1304229 ofs=446464
- <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1419147 ofs=450560
- <unknown>-12683 (-----) [005] .... 1920260.585498: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1349246 ofs=454656
- <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128519 ofs=458752
- <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125168 ofs=462848
- <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081031 ofs=20480
- <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293022 ofs=24576
- <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1113007 ofs=28672
- <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339312 ofs=32768
- <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412311 ofs=36864
- <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260960 ofs=40960
- <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189529 ofs=45056
- <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412184 ofs=49152
- <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1481227 ofs=53248
- <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1455940 ofs=57344
- <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299132 ofs=61440
- <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337375 ofs=65536
- <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328742 ofs=69632
- <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315646 ofs=73728
- <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225475 ofs=77824
- <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146097 ofs=81920
- <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1318775 ofs=86016
- <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448391 ofs=90112
- <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441412 ofs=94208
- <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138111 ofs=98304
- <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143223 ofs=102400
- <unknown>-12683 (-----) [005] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079876 ofs=466944
- <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447637 ofs=106496
- <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220585 ofs=110592
- <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449051 ofs=114688
- <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313180 ofs=118784
- <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313166 ofs=122880
- <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313154 ofs=126976
- <unknown>-12683 (-----) [005] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218394 ofs=471040
- <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144047 ofs=131072
- <unknown>-12683 (-----) [005] .... 1920260.585537: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218579 ofs=475136
- <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241332 ofs=135168
- <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1097199 ofs=139264
- <unknown>-12694 (-----) [006] .... 1920260.585545: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1214197 ofs=143360
- <unknown>-12694 (-----) [006] .... 1920260.585645: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197633 ofs=147456
- <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1311536 ofs=151552
- <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1322952 ofs=155648
- <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346974 ofs=159744
- <unknown>-12694 (-----) [006] .... 1920260.585648: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257232 ofs=163840
- <unknown>-12695 (-----) [004] .... 1920260.586355: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1204484 ofs=700416
- <unknown>-12695 (-----) [004] .... 1920260.586357: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326426 ofs=704512
- <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151808 ofs=708608
- <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209422 ofs=712704
- <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1408387 ofs=716800
- <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197336 ofs=720896
- <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1205652 ofs=724992
- <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133421 ofs=729088
- <unknown>-12695 (-----) [004] .... 1920260.586364: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092173 ofs=733184
- <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124430 ofs=737280
- <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143926 ofs=741376
- <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1090109 ofs=745472
- <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102012 ofs=749568
- <unknown>-12695 (-----) [004] .... 1920260.586367: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1154930 ofs=753664
- <unknown>-12695 (-----) [004] .... 1920260.586368: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1132993 ofs=757760
- <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1430780 ofs=761856
- <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197452 ofs=765952
- <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075111 ofs=770048
- <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1275616 ofs=774144
- <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1444981 ofs=778240
- <unknown>-12695 (-----) [004] .... 1920260.586371: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452592 ofs=782336
- <unknown>-12695 (-----) [004] .... 1920260.586374: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102857 ofs=786432
- <unknown>-12695 (-----) [004] .... 1920260.586376: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406969 ofs=790528
- <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1522553 ofs=794624
- <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260771 ofs=798720
- <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1474649 ofs=802816
- <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268708 ofs=806912
- <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346144 ofs=811008
- <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081167 ofs=815104
- <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137677 ofs=819200
- <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161175 ofs=823296
- <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461331 ofs=827392
- <unknown>-12695 (-----) [004] .... 1920260.586492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347219 ofs=831488
- <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1290004 ofs=835584
- <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299174 ofs=839680
- <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317595 ofs=843776
- <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1484924 ofs=847872
- <unknown>-12695 (-----) [004] .... 1920260.586497: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1169920 ofs=851968
- <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359189 ofs=856064
- <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307842 ofs=860160
- <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237858 ofs=864256
- <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189461 ofs=868352
- <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1223232 ofs=872448
- <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1104076 ofs=876544
- <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079223 ofs=880640
- <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092537 ofs=884736
- <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353960 ofs=888832
- <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346330 ofs=892928
- <unknown>-12695 (-----) [004] .... 1920260.586506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345764 ofs=897024
- <unknown>-12695 (-----) [004] .... 1920260.586507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1363913 ofs=901120
- <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1319570 ofs=905216
- <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1367024 ofs=909312
- <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1333808 ofs=913408
- <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158627 ofs=917504
- <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300368 ofs=921600
- <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1245363 ofs=925696
- <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345609 ofs=929792
- <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393826 ofs=933888
- <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200552 ofs=937984
- <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170885 ofs=942080
- <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1536209 ofs=946176
- <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189630 ofs=950272
- <unknown>-12695 (-----) [004] .... 1920260.586513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1121010 ofs=954368
- <unknown>-12695 (-----) [004] .... 1920260.586514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324474 ofs=958464
- <unknown>-12697 (-----) [007] .... 1920260.586578: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129628 ofs=299008
- <unknown>-12697 (-----) [007] .... 1920260.586579: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307120 ofs=303104
- <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347284 ofs=307200
- <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1312996 ofs=311296
- <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170623 ofs=315392
- <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359281 ofs=319488
- <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1180021 ofs=323584
- <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195728 ofs=327680
- <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163642 ofs=331776
- <unknown>-12697 (-----) [007] .... 1920260.586587: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1152538 ofs=335872
- <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345922 ofs=339968
- <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343604 ofs=344064
- <unknown>-12697 (-----) [007] .... 1920260.586721: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399371 ofs=479232
- <unknown>-12697 (-----) [007] .... 1920260.586723: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1106549 ofs=483328
- <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331546 ofs=487424
- <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299299 ofs=491520
- <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1288883 ofs=495616
- <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399049 ofs=499712
- <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146931 ofs=503808
- <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1296592 ofs=507904
- <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468397 ofs=512000
- <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215698 ofs=516096
- <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1177341 ofs=520192
- <unknown>-12697 (-----) [007] .... 1920260.586731: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189162 ofs=524288
- <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435997 ofs=528384
- <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209896 ofs=532480
- <unknown>-12697 (-----) [007] .... 1920260.586733: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1255888 ofs=536576
- <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1234200 ofs=540672
- <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1422854 ofs=544768
- <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435794 ofs=548864
- <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236279 ofs=552960
- <unknown>-12697 (-----) [007] .... 1920260.586736: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1485732 ofs=557056
- <unknown>-12683 (-----) [005] .... 1920260.586743: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1417198 ofs=561152
- <unknown>-12683 (-----) [005] .... 1920260.586746: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1469450 ofs=565248
- <unknown>-12696 (-----) [004] .... 1920260.587465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489023 ofs=1040384
- <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449498 ofs=1044480
- <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447737 ofs=1048576
- <unknown>-12696 (-----) [004] .... 1920260.587470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124530 ofs=1052672
- <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246743 ofs=1056768
- <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441927 ofs=1060864
- <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280581 ofs=1064960
- <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289438 ofs=1069056
- <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1464236 ofs=1073152
- <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125808 ofs=1077248
- <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1329385 ofs=1081344
- <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314093 ofs=1085440
- <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1201837 ofs=1089536
- <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1327734 ofs=1093632
- <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406568 ofs=1097728
- <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331873 ofs=1101824
- <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331898 ofs=1105920
- <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331917 ofs=1110016
- <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1332091 ofs=1114112
- <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1108186 ofs=1118208
- <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1182631 ofs=1122304
- <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1085941 ofs=1126400
- <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1433982 ofs=1130496
- <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1387028 ofs=1134592
- <unknown>-12696 (-----) [004] .... 1920260.587488: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353117 ofs=1138688
- <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1352364 ofs=1142784
- <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144513 ofs=1146880
- <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1403984 ofs=1150976
- <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278970 ofs=1155072
- <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326743 ofs=1159168
- <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1221809 ofs=1163264
- <unknown>-12696 (-----) [004] .... 1920260.587492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268668 ofs=1167360
- <unknown>-12695 (-----) [005] .... 1920260.587502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074544 ofs=962560
- <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074294 ofs=966656
- <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075097 ofs=970752
- <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162407 ofs=974848
- <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1141370 ofs=978944
- <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306487 ofs=983040
- <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306434 ofs=987136
- <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306347 ofs=991232
- <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306247 ofs=995328
- <unknown>-12695 (-----) [005] .... 1920260.587515: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306195 ofs=999424
- <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306039 ofs=1003520
- <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305983 ofs=1007616
- <unknown>-12694 (-----) [006] .... 1920260.587701: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1216391 ofs=1171456
- <unknown>-12694 (-----) [006] .... 1920260.587705: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1262462 ofs=1175552
- <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1358114 ofs=1179648
- <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1357898 ofs=1183744
- <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237003 ofs=1187840
- <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1126319 ofs=1191936
- <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1415489 ofs=1196032
- <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279558 ofs=1200128
- <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1434022 ofs=1204224
- <unknown>-12694 (-----) [006] .... 1920260.587709: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220130 ofs=1208320
- <unknown>-12694 (-----) [006] .... 1920260.587710: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163037 ofs=1212416
- <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404501 ofs=1216512
- <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406287 ofs=1220608
- <unknown>-12697 (-----) [007] .... 1920260.588132: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1355143 ofs=1376256
- <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1213923 ofs=1380352
- <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1243190 ofs=1384448
- <unknown>-12697 (-----) [007] .... 1920260.588143: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300698 ofs=1388544
- <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1482568 ofs=1392640
- <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461789 ofs=1396736
- <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242314 ofs=1400832
- <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1471996 ofs=1404928
- <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242742 ofs=1409024
- <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242579 ofs=1413120
- <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242553 ofs=1417216
- <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1457332 ofs=1421312
- <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315431 ofs=1425408
- <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080653 ofs=1429504
- <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324174 ofs=1433600
- <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324142 ofs=1437696
- <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1157760 ofs=1441792
- <unknown>-12697 (-----) [007] .... 1920260.588151: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075059 ofs=1445888
- <unknown>-12683 (-----) [006] .... 1920260.589785: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279192 ofs=1486848
- <unknown>-12683 (-----) [006] .... 1920260.589790: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278527 ofs=1490944
- <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1091778 ofs=1495040
- <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339447 ofs=1499136
- <unknown>-12683 (-----) [006] .... 1920260.589792: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1254007 ofs=1503232
- <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1115173 ofs=1507328
- <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393985 ofs=1511424
- <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1369123 ofs=1515520
- <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314257 ofs=1519616
- <unknown>-12683 (-----) [006] .... 1920260.589802: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404487 ofs=1523712
- <unknown>-12683 (-----) [006] .... 1920260.589803: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1354554 ofs=1527808
- <unknown>-12683 (-----) [006] .... 1920260.594312: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1141445 ofs=9801728
- <unknown>-12683 (-----) [006] .... 1920260.594322: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323774 ofs=231460864
- <unknown>-12683 (-----) [006] .... 1920260.594326: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323772 ofs=10993664
- <unknown>-12683 (-----) [006] .... 1920260.595212: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481305 ofs=9805824
- <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481306 ofs=9809920
- <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481316 ofs=9814016
- <unknown>-12683 (-----) [006] .... 1920260.595215: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481340 ofs=9818112
- <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394587 ofs=9822208
- <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103455 ofs=9826304
- <unknown>-12683 (-----) [006] .... 1920260.595217: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103271 ofs=9830400
- <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103168 ofs=9834496
- <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103145 ofs=9838592
- <unknown>-12683 (-----) [006] .... 1920260.595219: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103115 ofs=9842688
- <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103057 ofs=9846784
- <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1331958 ofs=9850880
- <unknown>-12683 (-----) [006] .... 1920260.595227: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1356305 ofs=9854976
- <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103708 ofs=9859072
- <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1099286 ofs=9863168
- <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435190 ofs=9867264
- <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1395504 ofs=9871360
- <unknown>-12683 (-----) [006] .... 1920260.595230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1352916 ofs=9875456
- <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1255529 ofs=9879552
- <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1336145 ofs=9883648
- <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1334143 ofs=9887744
- <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328548 ofs=9891840
- <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222215 ofs=9895936
- <unknown>-12683 (-----) [006] .... 1920260.595233: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1461056 ofs=9900032
- <unknown>-12683 (-----) [006] .... 1920260.595234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1228276 ofs=9904128
- <unknown>-12683 (-----) [006] .... 1920260.595235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1151188 ofs=9908224
- <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1443605 ofs=9912320
- <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1146821 ofs=9916416
- <unknown>-12683 (-----) [006] .... 1920260.595237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103669 ofs=9920512
- <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103744 ofs=9924608
- <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103868 ofs=9928704
- <unknown>-12683 (-----) [006] .... 1920260.595789: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465942 ofs=15855616
- <unknown>-12683 (-----) [006] .... 1920260.595792: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323712 ofs=261189632
- <unknown>-12683 (-----) [006] .... 1920260.595998: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323701 ofs=262094848
- <unknown>-12683 (-----) [006] .... 1920260.596191: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222287 ofs=15859712
- <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1213146 ofs=15863808
- <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310396 ofs=15867904
- <unknown>-12683 (-----) [006] .... 1920260.596193: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310177 ofs=15872000
- <unknown>-12683 (-----) [006] .... 1920260.596194: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1187914 ofs=15876096
- <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1322409 ofs=15880192
- <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1282484 ofs=15884288
- <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1097245 ofs=15888384
- <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416816 ofs=15892480
- <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1257125 ofs=15896576
- <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1403527 ofs=15900672
- <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1218006 ofs=15904768
- <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1153893 ofs=15908864
- <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328023 ofs=15912960
- <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465412 ofs=15917056
- <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1092448 ofs=15921152
- <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1239220 ofs=15925248
- <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1276491 ofs=15929344
- <unknown>-12683 (-----) [006] .... 1920260.596205: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1262240 ofs=15933440
- <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1323793 ofs=15937536
- <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1074937 ofs=15941632
- <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1311157 ofs=15945728
- <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1308442 ofs=15949824
- <unknown>-12683 (-----) [006] .... 1920260.596210: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1467709 ofs=15953920
- <unknown>-12683 (-----) [006] .... 1920260.596211: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394299 ofs=15958016
- <unknown>-12683 (-----) [004] .... 1920260.612586: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1316156 ofs=344064
- <unknown>-12683 (-----) [004] .... 1920260.612591: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1406323 ofs=348160
- <unknown>-12683 (-----) [004] .... 1920260.612601: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216972 ofs=352256
- <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1271924 ofs=356352
- <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1369225 ofs=360448
- <unknown>-12683 (-----) [004] .... 1920260.612608: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1318474 ofs=364544
- <unknown>-12683 (-----) [004] .... 1920260.612609: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1227283 ofs=368640
- <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1364376 ofs=372736
- <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1073400 ofs=376832
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
deleted file mode 100644
index ab3df45f8c54..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
deleted file mode 100644
index 17cb11662172..000000000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py
deleted file mode 100644
index 6071f145fe1d..000000000000
--- a/startop/scripts/lib/cmd_utils.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Helper util libraries for command line operations."""
-
-import asyncio
-import sys
-import time
-from typing import Tuple, Optional, List
-
-import lib.print_utils as print_utils
-
-TIMEOUT = 50
-SIMULATE = False
-
-def run_command_nofail(cmd: List[str], **kwargs) -> None:
- """Runs cmd list with default timeout.
-
- Throws exception if the execution fails.
- """
- my_kwargs = {"timeout": TIMEOUT, "shell": False, "simulate": False}
- my_kwargs.update(kwargs)
- passed, out = execute_arbitrary_command(cmd, **my_kwargs)
- if not passed:
- raise RuntimeError(
- "Failed to execute %s (kwargs=%s), output=%s" % (cmd, kwargs, out))
-
-def run_adb_shell_command(cmd: str) -> Tuple[bool, str]:
- """Runs command using adb shell.
-
- Returns:
- A tuple of running status (True=succeeded, False=failed or timed out) and
- std output (string contents of stdout with trailing whitespace removed).
- """
- return run_shell_command('adb shell "{}"'.format(cmd))
-
-def run_shell_func(script_path: str,
- func: str,
- args: List[str]) -> Tuple[bool, str]:
- """Runs shell function with default timeout.
-
- Returns:
- A tuple of running status (True=succeeded, False=failed or timed out) and
- std output (string contents of stdout with trailing whitespace removed) .
- """
- if args:
- cmd = 'bash -c "source {script_path}; {func} {args}"'.format(
- script_path=script_path,
- func=func,
- args=' '.join("'{}'".format(arg) for arg in args))
- else:
- cmd = 'bash -c "source {script_path}; {func}"'.format(
- script_path=script_path,
- func=func)
-
- print_utils.debug_print(cmd)
- return run_shell_command(cmd)
-
-def run_shell_command(cmd: str) -> Tuple[bool, str]:
- """Runs shell command with default timeout.
-
- Returns:
- A tuple of running status (True=succeeded, False=failed or timed out) and
- std output (string contents of stdout with trailing whitespace removed) .
- """
- return execute_arbitrary_command([cmd],
- TIMEOUT,
- shell=True,
- simulate=SIMULATE)
-
-def execute_arbitrary_command(cmd: List[str],
- timeout: int,
- shell: bool,
- simulate: bool) -> Tuple[bool, str]:
- """Run arbitrary shell command with default timeout.
-
- Mostly copy from
- frameworks/base/startop/scripts/app_startup/app_startup_runner.py.
-
- Args:
- cmd: list of cmd strings.
- timeout: the time limit of running cmd.
- shell: indicate if the cmd is a shell command.
- simulate: if it's true, do not run the command and assume the running is
- successful.
-
- Returns:
- A tuple of running status (True=succeeded, False=failed or timed out) and
- std output (string contents of stdout with trailing whitespace removed) .
- """
- if simulate:
- print(cmd)
- return True, ''
-
- print_utils.debug_print('[EXECUTE]', cmd)
- # block until either command finishes or the timeout occurs.
- loop = asyncio.get_event_loop()
-
- (return_code, script_output) = loop.run_until_complete(
- _run_command(*cmd, shell=shell, timeout=timeout))
-
- script_output = script_output.decode() # convert bytes to str
-
- passed = (return_code == 0)
- print_utils.debug_print('[$?]', return_code)
- if not passed:
- print('[FAILED, code:%s]' % (return_code), script_output, file=sys.stderr)
-
- return passed, script_output.rstrip()
-
-async def _run_command(*args: List[str],
- shell: bool = False,
- timeout: Optional[int] = None) -> Tuple[int, bytes]:
- if shell:
- process = await asyncio.create_subprocess_shell(
- *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
- else:
- process = await asyncio.create_subprocess_exec(
- *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
-
- script_output = b''
-
- print_utils.debug_print('[PID]', process.pid)
-
- timeout_remaining = timeout
- time_started = time.time()
-
- # read line (sequence of bytes ending with b'\n') asynchronously
- while True:
- try:
- line = await asyncio.wait_for(process.stdout.readline(),
- timeout_remaining)
- print_utils.debug_print('[STDOUT]', line)
- script_output += line
-
- if timeout_remaining:
- time_elapsed = time.time() - time_started
- timeout_remaining = timeout - time_elapsed
- except asyncio.TimeoutError:
- print_utils.debug_print('[TIMEDOUT] Process ', process.pid)
-
- print_utils.debug_print('[TIMEDOUT] Sending SIGTERM.')
- process.terminate()
-
- # 5 second timeout for process to handle SIGTERM nicely.
- try:
- (remaining_stdout,
- remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
- script_output += remaining_stdout
- except asyncio.TimeoutError:
- print_utils.debug_print('[TIMEDOUT] Sending SIGKILL.')
- process.kill()
-
- # 5 second timeout to finish with SIGKILL.
- try:
- (remaining_stdout,
- remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
- script_output += remaining_stdout
- except asyncio.TimeoutError:
- # give up, this will leave a zombie process.
- print_utils.debug_print('[TIMEDOUT] SIGKILL failed for process ',
- process.pid)
- time.sleep(100)
-
- return -1, script_output
- else:
- if not line: # EOF
- break
-
- code = await process.wait() # wait for child process to exit
- return code, script_output
diff --git a/startop/scripts/lib/logcat_utils.py b/startop/scripts/lib/logcat_utils.py
deleted file mode 100644
index 8a3d00b46771..000000000000
--- a/startop/scripts/lib/logcat_utils.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Helper util libraries for parsing logcat logs."""
-
-import asyncio
-import re
-from datetime import datetime
-from typing import Optional, Pattern
-
-# local import
-import lib.print_utils as print_utils
-
-def parse_logcat_datetime(timestamp: str) -> Optional[datetime]:
- """Parses the timestamp of logcat.
-
- Params:
- timestamp: for example "2019-07-01 16:13:55.221".
-
- Returns:
- a datetime of timestamp with the year now.
- """
- try:
- # Match the format of logcat. For example: "2019-07-01 16:13:55.221",
- # because it doesn't have year, set current year to it.
- timestamp = datetime.strptime(timestamp,
- '%Y-%m-%d %H:%M:%S.%f')
- return timestamp
- except ValueError as ve:
- print_utils.debug_print('Invalid line: ' + timestamp)
- return None
-
-def _is_time_out(timeout: datetime, line: str) -> bool:
- """Checks if the timestamp of this line exceeds the timeout.
-
- Returns:
- true if the timestamp exceeds the timeout.
- """
- # Get the timestampe string.
- cur_timestamp_str = ' '.join(re.split(r'\s+', line)[0:2])
- timestamp = parse_logcat_datetime(cur_timestamp_str)
- if not timestamp:
- return False
-
- return timestamp > timeout
-
-async def _blocking_wait_for_logcat_pattern(timestamp: datetime,
- pattern: Pattern,
- timeout: datetime) -> Optional[str]:
- # Show the year in the timestampe.
- logcat_cmd = 'adb logcat -v UTC -v year -v threadtime -T'.split()
- logcat_cmd.append(str(timestamp))
- print_utils.debug_print('[LOGCAT]:' + ' '.join(logcat_cmd))
-
- # Create subprocess
- process = await asyncio.create_subprocess_exec(
- *logcat_cmd,
- # stdout must a pipe to be accessible as process.stdout
- stdout=asyncio.subprocess.PIPE)
-
- while (True):
- # Read one line of output.
- data = await process.stdout.readline()
- line = data.decode('utf-8').rstrip()
-
- # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager: Displayed
- # com.android.settings/.Settings: +927ms
- # TODO: Detect timeouts even when there is no logcat output.
- if _is_time_out(timeout, line):
- print_utils.debug_print('DID TIMEOUT BEFORE SEEING ANYTHING ('
- 'timeout={timeout} seconds << {pattern} '
- '>>'.format(timeout=timeout, pattern=pattern))
- return None
-
- if pattern.match(line):
- print_utils.debug_print(
- 'WE DID SEE PATTERN << "{}" >>.'.format(pattern))
- return line
-
-def blocking_wait_for_logcat_pattern(timestamp: datetime,
- pattern: Pattern,
- timeout: datetime) -> Optional[str]:
- """Selects the line that matches the pattern and within the timeout.
-
- Returns:
- the line that matches the pattern and within the timeout.
- """
- loop = asyncio.get_event_loop()
- result = loop.run_until_complete(
- _blocking_wait_for_logcat_pattern(timestamp, pattern, timeout))
- return result
diff --git a/startop/scripts/lib/logcat_utils_test.py b/startop/scripts/lib/logcat_utils_test.py
deleted file mode 100644
index ab82515bc4fa..000000000000
--- a/startop/scripts/lib/logcat_utils_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-"""Unit tests for the logcat_utils.py script."""
-
-import asyncio
-import datetime
-import re
-
-import logcat_utils
-from mock import MagicMock, patch
-
-def test_parse_logcat_datatime():
- # Act
- result = logcat_utils.parse_logcat_datetime('2019-07-01 16:13:55.221')
-
- # Assert
- assert result == datetime.datetime(2019, 7, 1, 16, 13, 55, 221000)
-
-class AsyncMock(MagicMock):
- async def __call__(self, *args, **kwargs):
- return super(AsyncMock, self).__call__(*args, **kwargs)
-
-def _async_return():
- f = asyncio.Future()
- f.set_result(
- b'2019-07-01 15:51:53.290 27365 27392 I ActivityTaskManager: '
- b'Displayed com.google.android.music/com.android.music.activitymanagement.'
- b'TopLevelActivity: +1s7ms')
- return f
-
-def test_parse_displayed_time_succeed():
- # Act
- with patch('asyncio.create_subprocess_exec',
- new_callable=AsyncMock) as asyncio_mock:
- asyncio_mock.return_value.stdout.readline = _async_return
- timestamp = datetime.datetime(datetime.datetime.now().year, 7, 1, 16, 13,
- 55, 221000)
- timeout_dt = timestamp + datetime.timedelta(0, 10)
- pattern = re.compile('.*ActivityTaskManager: Displayed '
- 'com.google.android.music/com.android.music.*')
- result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
- pattern,
- timeout_dt)
-
- # Assert
- assert result == '2019-07-01 15:51:53.290 27365 27392 I ' \
- 'ActivityTaskManager: ' \
- 'Displayed com.google.android.music/com.android.music.' \
- 'activitymanagement.TopLevelActivity: +1s7ms'
-
-def _async_timeout_return():
- f = asyncio.Future()
- f.set_result(
- b'2019-07-01 17:51:53.290 27365 27392 I ActivityTaskManager: '
- b'Displayed com.google.android.music/com.android.music.activitymanagement.'
- b'TopLevelActivity: +1s7ms')
- return f
-
-def test_parse_displayed_time_timeout():
- # Act
- with patch('asyncio.create_subprocess_exec',
- new_callable=AsyncMock) as asyncio_mock:
- asyncio_mock.return_value.stdout.readline = _async_timeout_return
- timestamp = datetime.datetime(datetime.datetime.now().year,
- 7, 1, 16, 13, 55, 221000)
- timeout_dt = timestamp + datetime.timedelta(0, 10)
- pattern = re.compile('.*ActivityTaskManager: Displayed '
- 'com.google.android.music/com.android.music.*')
- result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
- pattern,
- timeout_dt)
-
- # Assert
- assert result == None
diff --git a/startop/scripts/lib/print_utils.py b/startop/scripts/lib/print_utils.py
deleted file mode 100644
index 8c5999d99d6e..000000000000
--- a/startop/scripts/lib/print_utils.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-"""Helper util libraries for debug printing."""
-
-import sys
-
-DEBUG = False
-
-def debug_print(*args, **kwargs):
- """Prints the args to sys.stderr if the DEBUG is set."""
- if DEBUG:
- print(*args, **kwargs, file=sys.stderr)
-
-def error_print(*args, **kwargs):
- print('[ERROR]:', *args, file=sys.stderr, **kwargs)
-
-def _expand_gen_repr(args):
- """Like repr but any generator-like object has its iterator consumed
- and then called repr on."""
- new_args_list = []
- for i in args:
- # detect iterable objects that do not have their own override of __str__
- if hasattr(i, '__iter__'):
- to_str = getattr(i, '__str__')
- if to_str.__objclass__ == object:
- # the repr for a generator is just type+address, expand it out instead.
- new_args_list.append([_expand_gen_repr([j])[0] for j in i])
- continue
- # normal case: uses the built-in to-string
- new_args_list.append(i)
- return new_args_list
-
-def debug_print_gen(*args, **kwargs):
- """Like _debug_print but will turn any iterable args into a list."""
- if not DEBUG:
- return
-
- new_args_list = _expand_gen_repr(args)
- debug_print(*new_args_list, **kwargs)
-
-def debug_print_nd(*args, **kwargs):
- """Like _debug_print but will turn any NamedTuple-type args into a string."""
- if not DEBUG:
- return
-
- new_args_list = []
- for i in args:
- if hasattr(i, '_field_types'):
- new_args_list.append("%s: %s" % (i.__name__, i._field_types))
- else:
- new_args_list.append(i)
-
- debug_print(*new_args_list, **kwargs)
diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py
deleted file mode 100644
index 42a33aff046d..000000000000
--- a/startop/scripts/trace_analyzer/lib/trace2db.py
+++ /dev/null
@@ -1,355 +0,0 @@
-#!/usr/bin/python3
-# 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.
-
-import re
-import sys
-
-from sqlalchemy import create_engine
-from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import relationship
-
-from sqlalchemy.orm import sessionmaker
-
-import sqlalchemy
-
-from typing import Optional, Tuple
-
-_DEBUG = False # print sql commands to console
-_FLUSH_LIMIT = 10000 # how many entries are parsed before flushing to DB from memory
-
-Base = declarative_base()
-
-class RawFtraceEntry(Base):
- __tablename__ = 'raw_ftrace_entries'
-
- id = Column(Integer, primary_key=True)
- task_name = Column(String, nullable=True) # <...> -> None.
- task_pid = Column(String, nullable=False)
- tgid = Column(Integer, nullable=True) # ----- -> None.
- cpu = Column(Integer, nullable=False)
- timestamp = Column(Float, nullable=False)
- function = Column(String, nullable=False)
- function_args = Column(String, nullable=False)
-
- # 1:1 relation with MmFilemapAddToPageCache.
- mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache",
- back_populates="raw_ftrace_entry")
-
- @staticmethod
- def parse_dict(line):
- # ' <...>-5521 (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266'
- m = re.match('\s*(.*)-(\d+)\s+\(([^\)]+)\)\s+\[(\d+)\]\s+([\w.]{4})\s+(\d+[.]\d+):\s+(\w+):\s+(.*)', line)
- if not m:
- return None
-
- groups = m.groups()
- # groups example:
- # ('<...>',
- # '5521',
- # '-----',
- # '003',
- # '...1',
- # '17148.446877',
- # 'tracing_mark_write',
- # 'trace_event_clock_sync: parent_ts=17148.447266')
- task_name = groups[0]
- if task_name == '<...>':
- task_name = None
-
- task_pid = int(groups[1])
- tgid = groups[2]
- if tgid == '-----':
- tgid = None
-
- cpu = int(groups[3])
- # irq_flags = groups[4]
- timestamp = float(groups[5])
- function = groups[6]
- function_args = groups[7]
-
- return {'task_name': task_name, 'task_pid': task_pid, 'tgid': tgid, 'cpu': cpu, 'timestamp': timestamp, 'function': function, 'function_args': function_args}
-
-class SchedSwitch(Base):
- __tablename__ = 'sched_switches'
-
- id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
- prev_comm = Column(String, nullable=False)
- prev_pid = Column(Integer, nullable=False)
- prev_prio = Column(Integer, nullable=False)
- prev_state = Column(String, nullable=False)
-
- next_comm = Column(String, nullable=False)
- next_pid = Column(Integer, nullable=False)
- next_prio = Column(Integer, nullable=False)
-
- @staticmethod
- def parse_dict(function_args, id = None):
- # 'prev_comm=kworker/u16:5 prev_pid=13971 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120'
- m = re.match("prev_comm=(.*) prev_pid=(\d+) prev_prio=(\d+) prev_state=(.*) ==> next_comm=(.*) next_pid=(\d+) next_prio=(\d+) ?", function_args)
- if not m:
- return None
-
- groups = m.groups()
- # ('kworker/u16:5', '13971', '120', 'S', 'swapper/4', '0', '120')
- d = {}
- if id is not None:
- d['id'] = id
- d['prev_comm'] = groups[0]
- d['prev_pid'] = int(groups[1])
- d['prev_prio'] = int(groups[2])
- d['prev_state'] = groups[3]
- d['next_comm'] = groups[4]
- d['next_pid'] = int(groups[5])
- d['next_prio'] = int(groups[6])
-
- return d
-
-class SchedBlockedReason(Base):
- __tablename__ = 'sched_blocked_reasons'
-
- id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
- pid = Column(Integer, nullable=False)
- iowait = Column(Integer, nullable=False)
- caller = Column(String, nullable=False)
-
- @staticmethod
- def parse_dict(function_args, id = None):
- # 'pid=2289 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f'
- m = re.match("pid=(\d+) iowait=(\d+) caller=(.*) ?", function_args)
- if not m:
- return None
-
- groups = m.groups()
- # ('2289', '1', 'wait_on_page_bit_common+0x2a8/0x5f8')
- d = {}
- if id is not None:
- d['id'] = id
- d['pid'] = int(groups[0])
- d['iowait'] = int(groups[1])
- d['caller'] = groups[2]
-
- return d
-
-class MmFilemapAddToPageCache(Base):
- __tablename__ = 'mm_filemap_add_to_page_caches'
-
- id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
- dev = Column(Integer, nullable=False) # decoded from ${major}:${minor} syntax.
- dev_major = Column(Integer, nullable=False) # original ${major} value.
- dev_minor = Column(Integer, nullable=False) # original ${minor} value.
-
- ino = Column(Integer, nullable=False) # decoded from hex to base 10
- page = Column(Integer, nullable=False) # decoded from hex to base 10
-
- pfn = Column(Integer, nullable=False)
- ofs = Column(Integer, nullable=False)
-
- # 1:1 relation with RawFtraceEntry.
- raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False)
-
- @staticmethod
- def parse_dict(function_args, id = None):
- # dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096
- m = re.match("dev (\d+):(\d+) ino ([0-9a-fA-F]+) page=([0-9a-fA-F]+) pfn=(\d+) ofs=(\d+)", function_args)
- if not m:
- return None
-
- groups = m.groups()
- # ('253', '6', 'b2c7', '00000000ec787cd9', '1478539', '4096')
- d = {}
- if id is not None:
- d['id'] = id
-
- device_major = d['dev_major'] = int(groups[0])
- device_minor = d['dev_minor'] = int(groups[1])
- d['dev'] = device_major << 8 | device_minor
- d['ino'] = int(groups[2], 16)
- d['page'] = int(groups[3], 16)
- d['pfn'] = int(groups[4])
- d['ofs'] = int(groups[5])
-
- return d
-
-class Trace2Db:
- def __init__(self, db_filename: str):
- (s, e) = self._init_sqlalchemy(db_filename)
- self._session = s
- self._engine = e
- self._raw_ftrace_entry_filter = lambda x: True
-
- def set_raw_ftrace_entry_filter(self, flt):
- """
- Install a function dict(RawFtraceEntry) -> bool
-
- If this returns 'false', then we skip adding the RawFtraceEntry to the database.
- """
- self._raw_ftrace_entry_filter = flt
-
- @staticmethod
- def _init_sqlalchemy(db_filename: str) -> Tuple[object, object]:
- global _DEBUG
- engine = create_engine('sqlite:///' + db_filename, echo=_DEBUG)
-
- # CREATE ... (tables)
- Base.metadata.create_all(engine)
-
- Session = sessionmaker(bind=engine)
- session = Session()
- return (session, engine)
-
- def parse_file_into_db(self, filename: str, limit: Optional[int] = None):
- """
- Parse the ftrace/systrace at 'filename',
- inserting the values into the current sqlite database.
-
- :return: number of RawFtraceEntry inserted.
- """
- return parse_file(filename, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
-
- def parse_file_buf_into_db(self, file_buf, limit: Optional[int] = None):
- """
- Parse the ftrace/systrace at 'filename',
- inserting the values into the current sqlite database.
-
- :return: number of RawFtraceEntry inserted.
- """
- return parse_file_buf(file_buf, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
-
-
- @property
- def session(self):
- return self._session
-
-def insert_pending_entries(engine, kls, lst):
- if len(lst) > 0:
- # for some reason, it tries to generate an empty INSERT statement with len=0,
- # which of course violates the first non-null constraint.
- try:
- # Performance-sensitive parsing according to:
- # https://docs.sqlalchemy.org/en/13/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow
- engine.execute(kls.__table__.insert(), lst)
- lst.clear()
- except sqlalchemy.exc.IntegrityError as err:
- # possibly violating some SQL constraint, print data here.
- print(err)
- print(lst)
- raise
-
-def parse_file(filename: str, *args, **kwargs) -> int:
- # use explicit encoding to avoid UnicodeDecodeError.
- with open(filename, encoding="ISO-8859-1") as f:
- return parse_file_buf(f, *args, **kwargs)
-
-def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int:
- global _FLUSH_LIMIT
- count = 0
- # count and id are not equal, because count still increases for invalid lines.
- id = 0
-
- pending_entries = []
- pending_sched_switch = []
- pending_sched_blocked_reasons = []
- pending_mm_filemap_add_to_pagecaches = []
-
- def insert_all_pending_entries():
- insert_pending_entries(engine, RawFtraceEntry, pending_entries)
- insert_pending_entries(engine, SchedSwitch, pending_sched_switch)
- insert_pending_entries(engine, SchedBlockedReason, pending_sched_blocked_reasons)
- insert_pending_entries(engine, MmFilemapAddToPageCache, pending_mm_filemap_add_to_pagecaches)
-
- # for trace.html files produced by systrace,
- # the actual ftrace is in the 'second' trace-data script class.
- parsing_trace_data = 0
- parsing_systrace_file = False
-
- f = filebuf
- for l in f:
- if parsing_trace_data == 0 and l == "<!DOCTYPE html>\n":
- parsing_systrace_file = True
- continue
- if parsing_trace_data != 2 and parsing_systrace_file:
- if l == ' <script class="trace-data" type="application/text">\n':
- parsing_trace_data = parsing_trace_data + 1
- continue
-
- if parsing_systrace_file and parsing_trace_data != 2:
- continue
- elif parsing_systrace_file and parsing_trace_data == 2 and l == " </script>\n":
- # the rest of this file is just random html
- break
-
- # now parsing the ftrace data.
- if len(l) > 1 and l[0] == '#':
- continue
-
- count = count + 1
-
- if limit and count >= limit:
- break
-
- raw_ftrace_entry = RawFtraceEntry.parse_dict(l)
- if not raw_ftrace_entry:
- print("WARNING: Failed to parse raw ftrace entry: " + l)
- continue
-
- if not raw_ftrace_entry_filter(raw_ftrace_entry):
- # Skip processing raw ftrace entries that don't match a filter.
- # This is an optimization for when Trace2Db is used programatically
- # to avoid having an overly large database.
- continue
-
- pending_entries.append(raw_ftrace_entry)
- id = id + 1
-
- if raw_ftrace_entry['function'] == 'sched_switch':
- sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id)
-
- if not sched_switch:
- print("WARNING: Failed to parse sched_switch: " + l)
- else:
- pending_sched_switch.append(sched_switch)
-
- elif raw_ftrace_entry['function'] == 'sched_blocked_reason':
- sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id)
-
- if not sbr:
- print("WARNING: Failed to parse sched_blocked_reason: " + l)
- else:
- pending_sched_blocked_reasons.append(sbr)
-
- elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache':
- d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'],
- id)
- if not d:
- print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l)
- else:
- pending_mm_filemap_add_to_pagecaches.append(d)
-
- # Objects are cached in python memory, not yet sent to SQL database.
-
- # Send INSERT/UPDATE/etc statements to the underlying SQL database.
- if count % _FLUSH_LIMIT == 0:
- insert_all_pending_entries()
-
- insert_all_pending_entries()
-
- # Ensure underlying database commits changes from memory to disk.
- session.commit()
-
- return count
diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py
deleted file mode 100755
index 3b326f000a7d..000000000000
--- a/startop/scripts/trace_analyzer/lib/trace2db_test.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-
-"""
-Unit tests for inode2filename module.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> ./inode2filename_test.py
- $> pytest inode2filename_test.py
- $> python -m pytest inode2filename_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-import io
-from copy import deepcopy
-
-# pip imports
-# local imports
-from trace2db import *
-
-# This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
-class EqualsSqlAlchemyObject:
- # For convenience to write shorter tests, we also add 'ignore_fields' which allow us to specify
- # which fields to ignore when doing the comparison.
- def __init__(self_, self, ignore_fields=[]):
- self_.self = self
- self_.ignore_fields = ignore_fields
-
- # Do field-by-field comparison.
- # It seems that SQLAlchemy does not implement __eq__ itself so we have to do it ourselves.
- def __eq__(self_, other):
- if isinstance(other, EqualsSqlAlchemyObject):
- other = other.self
-
- self = self_.self
-
- classes_match = isinstance(other, self.__class__)
- a, b = deepcopy(self.__dict__), deepcopy(other.__dict__)
-
- #compare based on equality our attributes, ignoring SQLAlchemy internal stuff
-
- a.pop('_sa_instance_state', None)
- b.pop('_sa_instance_state', None)
-
- for f in self_.ignore_fields:
- a.pop(f, None)
- b.pop(f, None)
-
- attrs_match = (a == b)
- return classes_match and attrs_match
-
- def __repr__(self):
- return repr(self.self.__dict__)
-
-
-def assert_eq_ignore_id(left, right):
- # This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
- # It does field-by-field comparison, but ignores the 'id' field.
- assert EqualsSqlAlchemyObject(left, ignore_fields=['id']) == EqualsSqlAlchemyObject(right)
-
-def parse_trace_file_to_db(*contents):
- """
- Make temporary in-memory sqlite3 database by parsing the string contents as a trace.
-
- :return: Trace2Db instance
- """
- buf = io.StringIO()
-
- for c in contents:
- buf.write(c)
- buf.write("\n")
-
- buf.seek(0)
-
- t2d = Trace2Db(":memory:")
- t2d.parse_file_buf_into_db(buf)
-
- buf.close()
-
- return t2d
-
-def test_ftrace_mm_filemap_add_to_pagecache():
- test_contents = """
-MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-MediaStoreImpor-27212 (27176) [000] .... 16136.595920: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000048e2e156 pfn=677645 ofs=126976
-MediaStoreImpor-27212 (27176) [000] .... 16136.597793: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000051eabfb2 pfn=677644 ofs=122880
-MediaStoreImpor-27212 (27176) [000] .... 16136.597815: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000ce7cd606 pfn=677643 ofs=131072
-MediaStoreImpor-27212 (27176) [000] .... 16136.603732: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=000000008ffd3030 pfn=730119 ofs=186482688
-MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
- <...>-27197 (-----) [002] .... 16136.613471: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000aca88a97 pfn=743346 ofs=241664
- <...>-27197 (-----) [002] .... 16136.615979: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000351f2bc1 pfn=777799 ofs=106496
- <...>-27224 (-----) [006] .... 16137.400090: mm_filemap_add_to_page_cache: dev 253:6 ino 712d page=000000006ff7ffdb pfn=754861 ofs=0
- <...>-1396 (-----) [000] .... 16137.451660: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000ba0cbb34 pfn=769173 ofs=187191296
- <...>-1396 (-----) [000] .... 16137.453020: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000f6ef038e pfn=820291 ofs=0
- <...>-1396 (-----) [000] .... 16137.453067: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000083ebc446 pfn=956463 ofs=4096
- <...>-1396 (-----) [000] .... 16137.453101: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009dc2cd25 pfn=822813 ofs=8192
- <...>-1396 (-----) [000] .... 16137.453113: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000a11167fb pfn=928650 ofs=12288
- <...>-1396 (-----) [000] .... 16137.453126: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000c1c3311b pfn=621110 ofs=16384
- <...>-1396 (-----) [000] .... 16137.453139: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009aa78342 pfn=689370 ofs=20480
- <...>-1396 (-----) [000] .... 16137.453151: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000082cddcd6 pfn=755584 ofs=24576
- <...>-1396 (-----) [000] .... 16137.453162: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000b0249bc7 pfn=691431 ofs=28672
- <...>-1396 (-----) [000] .... 16137.453183: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000006a776ff0 pfn=795084 ofs=32768
- <...>-1396 (-----) [000] .... 16137.453203: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000001a4918a7 pfn=806998 ofs=36864
- <...>-2578 (-----) [002] .... 16137.561871: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=187015168
- <...>-2578 (-----) [002] .... 16137.562846: mm_filemap_add_to_page_cache: dev 253:6 ino b25a page=000000002f6ba74f pfn=864982 ofs=0
- <...>-2578 (-----) [000] .... 16138.104500: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000f888d0f6 pfn=805812 ofs=192794624
- <...>-2578 (-----) [000] .... 16138.105836: mm_filemap_add_to_page_cache: dev 253:6 ino b7dd page=000000003749523b pfn=977196 ofs=0
- <...>-27215 (-----) [001] .... 16138.256881: mm_filemap_add_to_page_cache: dev 253:6 ino 758f page=000000001b375de1 pfn=755928 ofs=0
- <...>-27215 (-----) [001] .... 16138.257526: mm_filemap_add_to_page_cache: dev 253:6 ino 7591 page=000000004e039481 pfn=841534 ofs=0
- NonUserFacing6-5246 ( 1322) [005] .... 16138.356491: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=161890304
- NonUserFacing6-5246 ( 1322) [005] .... 16138.357538: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000002f6ba74f pfn=864982 ofs=0
- NonUserFacing6-5246 ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
- <...>-27197 (-----) [005] .... 16140.143224: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000a42527c6 pfn=1076669 ofs=32768
- """
-
- t2d = parse_trace_file_to_db(test_contents)
- session = t2d.session
-
- first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
-
- #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
- assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
-
- second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
-
- # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
- assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
-
-def test_systrace_mm_filemap_add_to_pagecache():
- test_contents = """
-<!DOCTYPE html>
-<html>
-<head i18n-values="dir:textdirection;">
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<meta charset="utf-8"/>
-<title>Android System Trace</title>
- <script class="trace-data" type="application/text">
-PROCESS DUMP
-USER PID PPID VSZ RSS WCHAN PC S NAME COMM
-root 1 0 62148 5976 0 0 S init [init]
-root 2 0 0 0 0 0 S [kthreadd] [kthreadd]
- </script>
-
- <script class="trace-data" type="application/text">
-MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-NonUserFacing6-5246 ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
- </script>
-
- <script class="trace-data" type="application/text">
-{"traceEvents": [{"category": "process_argv", "name": "process_argv", "args": {"argv": ["/mnt/ssd3/workspace/master/external/chromium-trace/systrace.py", "-t", "5", "pagecache"]}, "pid": 160383, "ts": 1037300940509.7991, "tid": 139628672526080, "ph": "M"}, {"category": "python", "name": "clock_sync", "args": {"issue_ts": 1037307346185.212, "sync_id": "9a7e4fe3-89ad-441f-8226-8fe533fe973e"}, "pid": 160383, "ts": 1037307351643.906, "tid": 139628726089536, "ph": "c"}], "metadata": {"clock-domain": "SYSTRACE"}}
- </script>
-<!-- END TRACE -->
- """
-
- t2d = parse_trace_file_to_db(test_contents)
- session = t2d.session
-
- first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
-
- #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
- assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
-
- second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
-
- # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
- assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
-
-def test_timestamp_filter():
- test_contents = """
- MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
- NonUserFacing6-5246 ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
- MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
- """
-
- t2d = parse_trace_file_to_db(test_contents)
- session = t2d.session
-
- end_time = 16137.0
-
- results = session.query(MmFilemapAddToPageCache).join(
- MmFilemapAddToPageCache.raw_ftrace_entry).filter(
- RawFtraceEntry.timestamp <= end_time).order_by(
- MmFilemapAddToPageCache.id).all()
-
- assert len(results) == 2
- assert_eq_ignore_id(
- MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0x7580, page=0x0000000060e990c7, pfn=677646,
- ofs=159744), results[0])
- assert_eq_ignore_id(
- MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
- ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676,
- ofs=0), results[1])
-
-
-if __name__ == '__main__':
- pytest.main()
diff --git a/startop/scripts/trace_analyzer/queries_all.sql b/startop/scripts/trace_analyzer/queries_all.sql
deleted file mode 100644
index 41d1c0804a7f..000000000000
--- a/startop/scripts/trace_analyzer/queries_all.sql
+++ /dev/null
@@ -1,57 +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.
- */
-
--- filter for atrace writes
-CREATE VIEW IF NOT EXISTS tracing_mark_writes AS
- SELECT *
- FROM raw_ftrace_entries
- WHERE function = 'tracing_mark_write';
-
--- split the tracing_mark_write function args by ||s
-DROP TABLE IF exists tracing_mark_write_split_array;
-
-CREATE TABLE tracing_mark_write_split_array (
- predictorset_id INT REFERENCES raw_ftrace_entries (id),
- predictor_name,
- rest,
- gen,
-
- UNIQUE(predictorset_id, gen) -- drops redundant inserts into table
-);
-
-CREATE INDEX "tracing_mark_write_split_array_id" ON tracing_mark_write_split_array (
- predictorset_id COLLATE BINARY COLLATE BINARY
-);
-
-INSERT INTO tracing_mark_write_split_array
- WITH
- split(predictorset_id, predictor_name, rest, gen) AS (
- -- split by |
- SELECT id, '', function_args || '|', 0 FROM tracing_mark_writes WHERE id
- UNION ALL
- SELECT predictorset_id,
- substr(rest, 0, instr(rest, '|')),
- substr(rest, instr(rest, '|')+1),
- gen + 1
- FROM split
- WHERE rest <> ''),
- split_results AS (
- SELECT * FROM split WHERE predictor_name <> ''
- )
- SELECT * from split_results
-;
-
-
diff --git a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql b/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
deleted file mode 100644
index c28475eec73d..000000000000
--- a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
+++ /dev/null
@@ -1,44 +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.
- */
-
--- use the 'launching: $process_name' async slice to figure out launch duration.
-DROP VIEW IF EXISTS launch_durations_named;
-
-CREATE VIEW launch_durations_named AS
-WITH
- launch_traces_raw AS (
- SELECT *
- FROM tracing_mark_write_split AS tmw,
- raw_ftrace_entries AS rfe
- WHERE atrace_message LIKE 'launching: %' AND rfe.id = tmw.raw_ftrace_entry_id
- ),
- launch_traces_joined AS (
- SELECT started.timestamp AS started_timestamp,
- finished.timestamp AS finished_timestamp,
- started.id AS started_id,
- finished.id AS finished_id,
- SUBSTR(started.atrace_message, 12) AS proc_name -- crop out "launching: " from the string.
- FROM launch_traces_raw AS started,
- launch_traces_raw AS finished
- -- async slices ('S' -> 'F') have matching counters given the same PID.
- WHERE started.atrace_type == 'S'
- AND finished.atrace_type == 'F'
- AND started.atrace_count == finished.atrace_count
- AND started.atrace_pid == finished.atrace_pid
- )
-SELECT * from launch_traces_joined;
-
-SELECT * FROM launch_durations_named;
diff --git a/startop/scripts/trace_analyzer/queries_block_launch.sql b/startop/scripts/trace_analyzer/queries_block_launch.sql
deleted file mode 100644
index 34e5f03d0c48..000000000000
--- a/startop/scripts/trace_analyzer/queries_block_launch.sql
+++ /dev/null
@@ -1,52 +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.
- */
-
-DROP VIEW IF EXISTS blocked_iowait_for_app_launches;
-
-CREATE VIEW blocked_iowait_for_app_launches AS
-WITH
- block_launch_join AS (
- SELECT *
- FROM blocking_durations AS bd,
- launch_durations_named AS ld
- WHERE bd.block_timestamp >= ld.started_timestamp
- AND bd.unblock_timestamp <= ld.finished_timestamp
- ),
- blocked_ui_threads AS (
- SELECT *
- FROM start_process_ui_threads AS sp,
- block_launch_join AS blj
- WHERE sp.atm_ui_thread_tid == unblock_pid
- AND sp.process_name = blj.proc_name
- ),
- summed_raw AS (
- SELECT SUM(unblock_timestamp-block_timestamp)*1000 AS sum_block_duration_ms,
- *
- FROM blocked_ui_threads
- GROUP BY unblock_pid
- ),
- summed_neat AS (
- SELECT sum_block_duration_ms AS blocked_iowait_duration_ms,
- process_name,
- (finished_timestamp - started_timestamp) * 1000 AS launching_duration_ms,
- started_timestamp * 1000 AS launching_started_timestamp_ms,
- finished_timestamp * 1000 AS launching_finished_timestamp_ms
- -- filter out the rest because its just selecting 1 arbitrary row (due to the SUM aggregate).,
- FROM summed_raw
- )
-SELECT * FROM summed_neat;
-
-SELECT * FROM blocked_iowait_for_app_launches;
diff --git a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql b/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
deleted file mode 100644
index 788d0dae47d3..000000000000
--- a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
+++ /dev/null
@@ -1,101 +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.
- */
-
-DROP VIEW IF EXISTS sched_switch_iowaits_pre;
-
--- scan for the closest pair such that:
--- sched_block_reason pid=$PID iowait=1 ...
--- ...
--- sched_switch next_pid=$PID
-CREATE VIEW sched_switch_iowaits_pre AS
- SELECT MAX(sbr.id) AS blocked_id,
- ss.id AS sched_switch_id,
- pid, -- iow.pid
- iowait, -- iowait=0 or iowait=1
- caller,
- sbr_f.timestamp AS blocked_timestamp,
- ss_f.timestamp AS sched_switch_timestamp,
- next_comm, -- name of next_pid
- next_pid -- same as iow.pid
- FROM sched_blocked_reasons AS sbr,
- raw_ftrace_entries AS sbr_f,
- sched_switches AS ss,
- raw_ftrace_entries AS ss_f
- WHERE sbr_f.id == sbr.id
- AND ss_f.id == ss.id
- AND sbr.pid == ss.next_pid
- AND sbr.iowait = 1
- AND sbr_f.timestamp < ss_f.timestamp -- ensures the 'closest' sched_blocked_reason is selected.
- GROUP BY ss.id
-;
-
-DROP VIEW IF EXISTS sched_switch_iowaits;
-
-CREATE VIEW sched_switch_iowaits AS
- SELECT *, MIN(sched_switch_timestamp) AS ss_timestamp -- drop all of the 'too large' sched_switch entries except the closest one.
- FROM sched_switch_iowaits_pre
- GROUP BY blocked_id;
-
-SELECT * FROM sched_switch_iowaits;
-
--- use a real table here instead of a view, otherwise SQLiteStudio segfaults for some reason.
-DROP TABLE IF EXISTS blocking_durations;
-
-CREATE TABLE blocking_durations AS
-WITH
- blocking_durations_raw AS (
- SELECT MAX(ss.id) AS block_id,
- ssf.timestamp AS block_timestamp,
- iow.sched_switch_timestamp AS unblock_timestamp,
- ss.prev_comm as block_prev_comm,
- iow.next_comm AS unblock_next_comm,
- ss.prev_state AS block_prev_state,
- iow.sched_switch_id AS unblock_id,
- iow.pid AS unblock_pid,
- iow.caller AS unblock_caller
- FROM sched_switches AS ss, -- this is the sched_switch that caused a block (in the future when it unblocks, the reason is iowait=1).
- sched_switch_iowaits AS iow, -- this is the sched_switch that removes the block (it is now running again).
- raw_ftrace_entries AS ssf
- WHERE ssf.id = ss.id AND ss.prev_pid == iow.next_pid AND ssf.timestamp < iow.sched_switch_timestamp
- GROUP BY unblock_timestamp
- ),
- blocking_durations_tmp AS (
- SELECT block_id,
- unblock_timestamp,
- block_timestamp,
- block_prev_comm as comm,
- block_prev_state as block_state,
- unblock_id,
- unblock_pid,
- unblock_caller
- FROM blocking_durations_raw
- )
- SELECT * FROM blocking_durations_tmp;-- ORDER BY block_id ASC;
- --SELECT SUM(block_duration_ms) AS sum, * FROM blocking_durations GROUP BY unblock_pid ORDER BY sum DESC;
-
-DROP INDEX IF EXISTS "blocking_durations_block_timestamp";
-
-CREATE INDEX "blocking_durations_block_timestamp" ON blocking_durations (
- block_timestamp COLLATE BINARY COLLATE BINARY
-);
-
-DROP INDEX IF EXISTS "blocking_durations_unblock_timestamp";
-
-CREATE INDEX "blocking_durations_unblock_timestamp" ON blocking_durations (
- unblock_timestamp COLLATE BINARY COLLATE BINARY
-);
-
-SELECT * FROM blocking_durations;
diff --git a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql b/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
deleted file mode 100644
index 0c166b09784c..000000000000
--- a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
+++ /dev/null
@@ -1,42 +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.
- */
-
-DROP VIEW IF EXISTS sched_switch_next_comm_pids;
-
-CREATE VIEW IF NOT EXISTS sched_switch_next_comm_pids AS
-
--- TODO: switch to using sched_switches table.
-
-WITH
- sched_switchs AS (
- SELECT * FROM raw_ftrace_entries WHERE function = 'sched_switch' AND function_args LIKE '% next_pid=%' AND function_args NOT LIKE '% next_comm=main %'
- ),
- comm_and_pids_raws AS (
- SELECT id,
- SUBSTR(function_args, instr(function_args, "next_comm="), instr(function_args, "next_pid=") - instr(function_args, "next_comm=")) AS next_comm_raw,
- SUBSTR(function_args, instr(function_args, "next_pid="), instr(function_args, "next_prio=") - instr(function_args, "next_pid=")) AS next_pid_raw
- FROM sched_switchs
- ),
- comm_and_pids AS (
- SELECT id,
- id AS raw_ftrace_entry_id,
- TRIM(SUBSTR(next_pid_raw, 10)) AS next_pid, -- len("next_pid=") is 10
- TRIM(SUBSTR(next_comm_raw, 11)) AS next_comm -- len("next_comm=") is 11
- FROM comm_and_pids_raws
- )
-SELECT * from comm_and_pids;
-
-SELECT * from sched_switch_next_comm_pids;
diff --git a/startop/scripts/trace_analyzer/queries_get_procs.sql b/startop/scripts/trace_analyzer/queries_get_procs.sql
deleted file mode 100644
index 06871c6e16b6..000000000000
--- a/startop/scripts/trace_analyzer/queries_get_procs.sql
+++ /dev/null
@@ -1,30 +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.
- */
-
-DROP VIEW IF EXISTS start_procs;
-
-CREATE VIEW IF NOT EXISTS start_procs AS
-WITH
- start_procs_raw AS (
- SELECT * from tracing_mark_write_split WHERE atrace_message LIKE 'Start proc: %'
- ),
- start_procs_substr AS (
- -- note: "12" is len("Start proc: ")+1. sqlite indices start at 1.
- SELECT raw_ftrace_entry_id, atrace_pid, SUBSTR(atrace_message, 13) AS process_name FROM start_procs_raw
- )
-SELECT * from start_procs_substr;
-
-SELECT * from start_procs;
diff --git a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql b/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
deleted file mode 100644
index 876e50e9880a..000000000000
--- a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
+++ /dev/null
@@ -1,88 +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.
- */
-
--- note: These queries do comparisons based on raw_ftrace_entries.id by treating it as if it was equivalent to the temporal timestamp.
--- in practice, the ID of raw_ftrace_entries is based on its order in the ftrace buffer [and on the same cpu its equivalent].
--- we can always resort raw_ftrace_entries to ensure id order matches timestamp order. We should rarely need to compare by timestamp directly.
--- accessing 'floats' is inferior as they are harder to index, and will result in slower queries.
---
--- Naming convention note: '_fid' corresponds to 'raw_ftrace_entry.id'.
-DROP VIEW IF EXISTS start_process_ui_threads;
-
--- Map of started process names to their UI thread's TID (as returned by gettid).
-CREATE VIEW IF NOT EXISTS start_process_ui_threads AS
-WITH
- start_proc_tids AS (
- SELECT sp.raw_ftrace_entry_id AS start_proc_fid,
- sp.atrace_pid AS atrace_pid,
- sp.process_name AS process_name,
- --MIN(nc.raw_ftrace_entry_id) as next_comm_fid,
- nc.raw_ftrace_entry_id AS next_comm_fid,
- nc.next_pid as next_pid,
- nc.next_comm as next_comm,
- SUBSTR(sp.process_name, -15) AS cut -- why -15? See TASK_MAX in kernel, the sched_switch name is truncated to 16 bytes.
- FROM start_procs AS sp,
- sched_switch_next_comm_pids AS nc
- WHERE sp.process_name LIKE '%' || nc.next_comm -- kernel truncates the sched_switch::next_comm event, so we must match the prefix of the full name.
- --WHERE SUBSTR(sp.process_name, -16) == nc.next_comm
- --WHERE cut == nc.next_comm
- ),
- start_proc_tids_filtered AS (
- SELECT *
- FROM start_proc_tids
- WHERE next_comm_fid > start_proc_fid -- safeguard that avoids choosing "earlier" sched_switch before process was even started.
- --ORDER BY start_proc_fid, next_comm_fid
- ),
- start_proc_all_threads AS (
- SELECT DISTINCT
- start_proc_fid, -- this is the ftrace entry of the system server 'Start proc: $process_name'. only need this to join for timestamp.
- process_name, -- this is the '$process_name' from the system server entry.
- -- next up we have all the possible thread IDs as parsed from sched_switch that corresponds most closest to the start proc.
- next_pid AS ui_thread_tpid, -- sched_switch.next_pid. This can be any of the threads in that process, it's not necessarily the main UI thread yet.
- next_comm,
- MIN(next_comm_fid) AS next_comm_fid -- don't pick the 'later' next_comm_fid because it could correspond to another app start.
- FROM start_proc_tids_filtered
- GROUP BY start_proc_fid, ui_thread_tpid
- ),
- activity_thread_mains AS (
- SELECT * FROM tracing_mark_write_split WHERE atrace_message = 'ActivityThreadMain'
- ),
- start_proc_ui_threads AS (
- SELECT start_proc_fid,
- process_name,
- ui_thread_tpid,
- next_comm,
- next_comm_fid,
- atm.raw_ftrace_entry_id as atm_fid,
- atm.atrace_pid as atm_ui_thread_tid
- FROM start_proc_all_threads AS spt,
- activity_thread_mains AS atm
- WHERE atm.atrace_pid == spt.ui_thread_tpid AND atm.raw_ftrace_entry_id > spt.start_proc_fid -- Ensure we ignore earlier ActivityThreadMains prior to their Start proc.
- ),
- start_proc_ui_threads_filtered AS (
- SELECT start_proc_fid,
- process_name, -- e.g. 'com.android.settings'
- --ui_thread_tpid,
- --next_comm,
- --next_comm_fid,
- MIN(atm_fid) AS atm_fid,
- atm_ui_thread_tid -- equivalent to gettid() for the process's UI thread.
- FROM start_proc_ui_threads
- GROUP BY start_proc_fid, atm_ui_thread_tid -- find the temporally closest ActivityTaskMain to a "Start proc: $process_name"
- )
-SELECT * FROM start_proc_ui_threads_filtered;
-
-SELECT * FROM start_process_ui_threads;
diff --git a/startop/scripts/trace_analyzer/queries_mark_write_join.sql b/startop/scripts/trace_analyzer/queries_mark_write_join.sql
deleted file mode 100644
index 100f07403423..000000000000
--- a/startop/scripts/trace_analyzer/queries_mark_write_join.sql
+++ /dev/null
@@ -1,53 +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.
- */
-
-DROP TABLE IF EXISTS tracing_mark_write_split;
-
-CREATE TABLE tracing_mark_write_split (
- raw_ftrace_entry_id INT REFERENCES raw_ftrace_entries (id),
- atrace_type CHAR(1), -- only null for the first 2 sync timers. usually 'B', 'C', E', ...
- atrace_pid INT, -- only null for first 2 sync timers
- atrace_message, -- usually null for type='E' etc.
- atrace_count, -- usually non-null only for 'C'
-
- UNIQUE(raw_ftrace_entry_id) -- drops redundant inserts into table
-);
-
-INSERT INTO tracing_mark_write_split
-WITH
- pivoted AS (
- SELECT tx.predictorset_id,
- --ty.predictorset_id,
- --tz.predictorset_id,
- --tzz.predictorset_id,
- tx.predictor_name AS atrace_type,
- CAST(ty.predictor_name AS integer) AS atrace_pid,
- tz.predictor_name AS atrace_message,
- CAST(tzz.predictor_name AS integer) AS atrace_count
- FROM (SELECT * from tracing_mark_write_split_array WHERE gen = 1) AS tx
- LEFT JOIN
- (SELECT * FROM tracing_mark_write_split_array WHERE gen = 2) AS ty
- ON tx.predictorset_id = ty.predictorset_id
- LEFT JOIN
- (SELECT * FROM tracing_mark_write_split_array WHERE gen = 3) AS tz
- ON tx.predictorset_id = tz.predictorset_id
- LEFT JOIN
- (SELECT * FROM tracing_mark_write_split_array WHERE gen = 4) AS tzz
- ON tx.predictorset_id = tzz.predictorset_id
- )
-SELECT * from pivoted ORDER BY predictorset_id;-- LIMIT 100;
-
-SELECT * FROM tracing_mark_write_split;
diff --git a/startop/scripts/trace_analyzer/run-sql-queries b/startop/scripts/trace_analyzer/run-sql-queries
deleted file mode 100755
index 61a0ad42a339..000000000000
--- a/startop/scripts/trace_analyzer/run-sql-queries
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-# 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.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ $# -lt 1 ]]; then
- echo "Usage: $0 <db-file>"
-fi
-
-DB_TARGET=$1
-
-if ! [[ -f $DB_TARGET ]]; then
- echo "ERROR: File '$DB_TARGET' does not exist." >&2
- exit 1
-fi
-
-exec_sql_file() {
- local filename="$1"
- if ! [[ -f $filename ]]; then
- echo "ERROR: Can't exec SQL file, '$filename' does not exist." >&2
- return 1
- fi
-
- sqlite3 "$DB_TARGET" < "$DIR"/"$filename"
-}
-
-exec_sql_file_quiet() {
- exec_sql_file "$@" > /dev/null
-}
-
-# Some views/tables need other views already created, so order does matter.
-# x -> y , means x depends on y.
-
-# View: tracing_mark_writes
-# Table: tracing_mark_write_split_array -> tracing_mark_writes
-exec_sql_file_quiet "queries_all.sql"
-
-# Table: tracing_mark_write_split -> tracing_mark_write_split_array
-exec_sql_file_quiet "queries_mark_write_join.sql"
-
-# View: start_procs -> tracing_mark_write_split
-exec_sql_file_quiet "queries_get_procs.sql"
-
-# View: sched_switch_next_comm_pids
-exec_sql_file_quiet "queries_get_comm_and_pids.sql"
-
-# View: start_process_ui_threads -> start_procs, sched_switch_next_comm_pids
-exec_sql_file_quiet "queries_get_ui_threads.sql"
-
-# View: launch_durations_named -> tracing_mark_write_split
-exec_sql_file_quiet "queries_app_launch_spans_with_name.sql"
-
-# View: sched_switch_iowaits_pre
-# View: sched_switch_iowaits -> sched_switch_iowaits_pre
-# Table: blocking_durations -> sched_switch_iowaits
-exec_sql_file_quiet "queries_find_sched_switch_unblocked.sql"
-
-# View: blocked_iowait_for_app_launches -> launch_durations_named, blocking_durations
-exec_sql_file_quiet "queries_block_launch.sql"
-
-#####
-#####
-#####
-
-# Final queries
-
-exec_sql_file "queries_pretty_print_block_launch.sql"
diff --git a/startop/scripts/trace_analyzer/test_fixtures/common_systrace b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
deleted file mode 100644
index 802cb5562593..000000000000
--- a/startop/scripts/trace_analyzer/test_fixtures/common_systrace
+++ /dev/null
@@ -1,518 +0,0 @@
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 411983/411983 #P:8
-#
-# _-----=> irqs-off
-# / _----=> need-resched
-# | / _---=> hardirq/softirq
-# || / _--=> preempt-depth
-# ||| / delay
-# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION
-# | | | | |||| | |
- <...>-14603 (-----) [000] ...1 14592.893157: tracing_mark_write: trace_event_clock_sync: parent_ts=14592.892578
- <...>-14603 (-----) [000] ...1 14592.893172: tracing_mark_write: trace_event_clock_sync: realtime_ts=1557129597951
- <...>-18150 (-----) [004] d..2 14594.182110: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:16 next_pid=23269 next_prio=120
- kworker/u16:16-23269 (23269) [004] d.h3 14594.182228: sched_blocked_reason: pid=18150 iowait=0 caller=a6xx_oob_set+0x194/0x3dc
- kworker/u16:16-23269 (23269) [004] d..2 14594.182248: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.182312: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.182488: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- kworker/u16:16-23269 (23269) [005] d..2 14594.182610: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.182626: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.182755: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.182975: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.183209: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.183371: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.184286: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
- kworker/u16:16-23269 (23269) [005] d..2 14594.184495: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
- <...>-18150 (-----) [004] d..2 14594.184498: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
- ksoftirqd/4-47 ( 47) [004] d..2 14594.185678: sched_switch: prev_comm=ksoftirqd/4 prev_pid=47 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
- kworker/6:2-10610 (10610) [006] d..2 14594.186012: sched_switch: prev_comm=kworker/6:2 prev_pid=10610 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-656 (-----) [001] .... 14594.219464: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-1803 (-----) [000] d..2 14594.219595: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-3359 (-----) [001] ...1 14594.219856: tracing_mark_write: S|1368|launching: com.google.android.dialer|0
- <...>-3359 (-----) [001] ...1 14594.219863: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunched
- <...>-3359 (-----) [001] ...1 14594.219869: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
- <...>-1398 (-----) [006] ...1 14594.220160: tracing_mark_write: B|1368|updateInputWindows
- <...>-3359 (-----) [001] .... 14594.220230: binder_set_priority: proc=1368 thread=3359 old=110 => new=120 desired=120
- <...>-1398 (-----) [006] ...1 14594.220588: tracing_mark_write: B|1368|android.os.Handler: com.android.server.wm.AppWindowToken$1
- <...>-1398 (-----) [006] ...1 14594.220722: tracing_mark_write: B|1368|ResourcesManager#getResources
- <...>-1052 (-----) [002] d..2 14594.220884: sched_switch: prev_comm=statsd.writer prev_pid=1052 prev_prio=120 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
- <...>-1398 (-----) [006] ...1 14594.220926: tracing_mark_write: B|1368|Theme::ApplyStyle
- <...>-1398 (-----) [006] ...1 14594.220929: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-2007 (-----) [007] ...1 14594.220996: tracing_mark_write: B|2007|Choreographer#doFrame
- <...>-2007 (-----) [007] ...1 14594.221005: tracing_mark_write: B|2007|animation
- <...>-1398 (-----) [006] ...1 14594.221015: tracing_mark_write: B|1368|ResourcesManager#getResources
- <...>-2045 (-----) [002] ...2 14594.221035: binder_set_priority: proc=1368 thread=1903 old=120 => new=118 desired=118
- <...>-2045 (-----) [002] d..2 14594.221065: sched_switch: prev_comm=UiThreadHelper prev_pid=2045 prev_prio=118 prev_state=S ==> next_comm=Binder:1368_4 next_pid=1903 next_prio=118
- <...>-1398 (-----) [006] ...1 14594.221080: tracing_mark_write: B|1368|AssetManager::SetApkAssets
- <...>-2007 (-----) [007] ...1 14594.221110: tracing_mark_write: B|2007|traversal
- <...>-656 (-----) [000] ...1 14594.221137: tracing_mark_write: B|625|requestNextVsync
- <...>-656 (-----) [000] ...1 14594.221141: tracing_mark_write: B|625|resetIdleTimer
- <...>-2007 (-----) [007] ...1 14594.221146: tracing_mark_write: B|2007|draw
- <...>-2007 (-----) [007] ...1 14594.221160: tracing_mark_write: B|2007|Record View#draw()
- <...>-660 (-----) [005] d..2 14594.221285: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
- <...>-658 (-----) [004] d..2 14594.221327: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=android.display next_pid=1397 next_prio=117
- <...>-2738 (-----) [005] ...1 14594.221342: tracing_mark_write: B|2007|notifyFramePending
- <...>-2738 (-----) [005] ...1 14594.221362: tracing_mark_write: B|2007|DrawFrame
- <...>-2738 (-----) [005] ...1 14594.221369: tracing_mark_write: B|2007|query
- <...>-2007 (-----) [007] d..2 14594.221369: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-1903 (-----) [002] .... 14594.221397: binder_set_priority: proc=1368 thread=1903 old=118 => new=120 desired=120
- <...>-2738 (-----) [005] ...2 14594.221400: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-2738 (-----) [005] d..2 14594.221430: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-1368 (-----) [003] ...1 14594.221431: tracing_mark_write: B|1368|Lock contention on GC thread flip lock (owner tid: 0)
- <...>-656 (-----) [005] ...1 14594.221460: tracing_mark_write: B|625|query
- <...>-656 (-----) [005] .... 14594.221528: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-2738 (-----) [007] ...1 14594.221552: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...2 14594.221563: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-2738 (-----) [007] d..2 14594.221600: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-1368 (-----) [003] d..2 14594.221623: sched_switch: prev_comm=system_server prev_pid=1368 prev_prio=118 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
- <...>-656 (-----) [007] ...1 14594.221628: tracing_mark_write: B|625|query
- <...>-23031 (-----) [001] d..2 14594.221643: sched_switch: prev_comm=UiAutomation prev_pid=23031 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-2738 (-----) [007] ...1 14594.221664: tracing_mark_write: B|2007|syncFrameState
- <...>-2738 (-----) [007] ...1 14594.221697: tracing_mark_write: B|2007|prepareTree
- <...>-23008 (-----) [005] d..2 14594.221706: sched_switch: prev_comm=hub.uiautomator prev_pid=23008 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
- <...>-656 (-----) [000] .... 14594.221737: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-1803 (-----) [003] d..2 14594.221747: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
- <...>-1397 (-----) [004] d..2 14594.221806: sched_switch: prev_comm=android.display prev_pid=1397 prev_prio=117 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
- <...>-1398 (-----) [006] d..2 14594.221816: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=R ==> next_comm=s.nexuslauncher next_pid=2007 next_prio=110
- <...>-2738 (-----) [007] ...1 14594.221824: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221830: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221834: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221841: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221843: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221846: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.221850: tracing_mark_write: B|2007|dequeueBuffer
- <...>-2738 (-----) [007] ...2 14594.221864: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-2738 (-----) [007] d..2 14594.221985: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=crtc_event:97 next_pid=303 next_prio=83
- <...>-2007 (-----) [006] ...1 14594.221989: tracing_mark_write: B|2007|topResumedActivityChangeItem
- <...>-303 (-----) [007] d..2 14594.222016: sched_switch: prev_comm=crtc_event:97 prev_pid=303 prev_prio=83 prev_state=S ==> next_comm=rcu_preempt next_pid=7 next_prio=120
- rcu_preempt-7 ( 7) [007] d..2 14594.222035: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
- migration/4-46 ( 46) [004] d..2 14594.222037: sched_switch: prev_comm=migration/4 prev_pid=46 prev_prio=0 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-2738 (-----) [007] d..2 14594.222039: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
- <...>-656 (-----) [004] ...1 14594.222100: tracing_mark_write: B|625|dequeueBuffer
- <...>-656 (-----) [004] ...1 14594.222114: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
- <...>-2007 (-----) [006] ...2 14594.222131: binder_set_priority: proc=1368 thread=1903 old=120 => new=110 desired=110
- <...>-2007 (-----) [006] d..2 14594.222143: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
- <...>-2613 (-----) [001] d..2 14594.222158: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-18150 (-----) [007] d..2 14594.222193: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-656 (-----) [004] .... 14594.222220: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-2738 (-----) [007] ...1 14594.222267: tracing_mark_write: B|2007|HWC release fence 36027 has signaled
- <...>-656 (-----) [007] ...1 14594.223842: tracing_mark_write: B|625|queueBuffer
- <...>-656 (-----) [007] ...1 14594.223845: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
- <...>-656 (-----) [007] ...1 14594.223871: tracing_mark_write: B|625|requestNextVsync
- <...>-656 (-----) [007] ...1 14594.223873: tracing_mark_write: B|625|resetIdleTimer
- <...>-656 (-----) [007] ...1 14594.223881: tracing_mark_write: B|625|addAndGetFrameTimestamps
- <...>-1395 (-----) [001] d..2 14594.223909: sched_switch: prev_comm=android.ui prev_pid=1395 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-2738 (-----) [007] ...1 14594.223959: tracing_mark_write: B|2007|Trace GPU completion fence 36027
- <...>-11799 (-----) [006] ...1 14594.224006: tracing_mark_write: B|2007|waiting for GPU completion 36027
- <...>-11799 (-----) [006] ...1 14594.224009: tracing_mark_write: B|2007|waitForever
- <...>-2613 (-----) [004] d..2 14594.224014: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=Binder:1803_6 next_pid=2173 next_prio=120
- <...>-11799 (-----) [006] d..1 14594.224014: fence_enable_signal: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78002
- <...>-11799 (-----) [006] d..2 14594.224021: sched_switch: prev_comm=GPU completion prev_pid=11799 prev_prio=110 prev_state=S ==> next_comm=rcuop/6 next_pid=68 next_prio=120
- rcuop/6-68 ( 68) [006] d..2 14594.224044: sched_switch: prev_comm=rcuop/6 prev_pid=68 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-259 (-----) [006] d..2 14594.224132: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
- <...>-3206 (-----) [001] d..2 14594.224167: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=R ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
- lowpool[847]-14589 ( 2446) [005] d..1 14594.224300: mm_filemap_delete_from_page_cache: dev 0:1 ino 3d0034 page=000000008247d586 pfn=676904 ofs=0
- <...>-1803 (-----) [001] d..2 14594.224302: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=aiai-vc-0 next_pid=3206 next_prio=139
- <...>-3206 (-----) [001] d..2 14594.224433: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-1903 (-----) [003] ...1 14594.224490: tracing_mark_write: B|1368|dispatchingStartProcess:com.google.android.dialer
- <...>-1903 (-----) [003] ...1 14594.224659: tracing_mark_write: B|1368|wmLayout
- <...>-1903 (-----) [003] ...1 14594.224666: tracing_mark_write: B|1368|performSurfacePlacement
- <...>-1903 (-----) [003] ...1 14594.224683: tracing_mark_write: B|1368|applySurfaceChanges
- <...>-1903 (-----) [003] ...1 14594.224688: tracing_mark_write: B|1368|openSurfaceTransaction
- <...>-2738 (-----) [007] ...1 14594.224711: tracing_mark_write: B|2007|query
- <...>-1903 (-----) [003] ...1 14594.224714: tracing_mark_write: B|1368|performLayout
- <...>-2738 (-----) [007] ...1 14594.224714: tracing_mark_write: B|2007|query
- <...>-1903 (-----) [003] ...1 14594.224723: tracing_mark_write: B|1368|applyPostLayoutPolicy
- <...>-2738 (-----) [007] d..2 14594.224752: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-656 (-----) [007] .... 14594.224766: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-1398 (-----) [002] ...1 14594.224801: tracing_mark_write: B|1368|Theme::ApplyStyle
- <...>-1398 (-----) [002] ...1 14594.224805: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224820: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224826: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224833: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224838: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224846: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224853: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224859: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-1398 (-----) [002] ...1 14594.224864: tracing_mark_write: B|1368|AssetManager::GetBag
- <...>-18150 (-----) [006] d..2 14594.228407: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
- <...>-2738 (-----) [007] d..2 14594.228411: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
- <...>-1409 (-----) [004] ...1 14594.228417: tracing_mark_write: B|1368|Start proc: com.google.android.dialer
- <...>-440 (-----) [006] d..2 14594.228418: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
- <...>-76 (-----) [007] d..2 14594.228430: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
- <...>-440 (-----) [007] d..2 14594.228434: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
- <...>-18150 (-----) [006] d..3 14594.228442: sched_blocked_reason: pid=1398 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
- <...>-76 (-----) [007] d..2 14594.228442: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
- <...>-2738 (-----) [007] ...2 14594.228446: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-18150 (-----) [006] d..2 14594.228447: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=110
- <...>-2738 (-----) [007] d..2 14594.228479: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-1409 (-----) [004] d..2 14594.228499: sched_switch: prev_comm=ActivityManager prev_pid=1409 prev_prio=118 prev_state=D ==> next_comm=Binder:965_2 next_pid=1041 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229271: tracing_mark_write: B|625|handleTransaction
- <...>-1773 (-----) [004] .... 14594.229285: binder_set_priority: proc=625 thread=1773 old=110 => new=120 desired=120
- <...>-440 (-----) [007] d..2 14594.229301: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
- <...>-2738 (-----) [007] ...1 14594.229318: tracing_mark_write: B|2007|HWC release fence 36028 has signaled
- <...>-2738 (-----) [007] ...1 14594.229331: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.229337: tracing_mark_write: B|2007|eglBeginFrame
- <...>-2738 (-----) [007] ...1 14594.229352: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...1 14594.229354: tracing_mark_write: B|2007|query
- <...>-791 (-----) [000] d..2 14594.229357: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229440: tracing_mark_write: B|625|doTransaction
- <...>-13916 (-----) [002] d..2 14594.229482: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=D|K ==> next_comm=swapper/2 next_pid=0 next_prio=120
- <...>-13917 (-----) [001] d..2 14594.229492: sched_blocked_reason: pid=13916 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-625 (-----) [003] ...1 14594.229492: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229507: tracing_mark_write: B|625|doTransaction
- <...>-13917 (-----) [001] d..2 14594.229523: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-13916 (-----) [002] d..2 14594.229535: sched_blocked_reason: pid=13917 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-625 (-----) [003] ...1 14594.229538: tracing_mark_write: B|625|doTransaction
- <...>-2738 (-----) [007] ...1 14594.229543: tracing_mark_write: B|2007|flush commands
- <...>-13916 (-----) [002] .... 14594.229562: sched_process_exit: comm=HeapTaskDaemon pid=13916 prio=124
- <...>-625 (-----) [003] ...1 14594.229567: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229588: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229628: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229652: tracing_mark_write: B|625|doTransaction
- <...>-13916 (-----) [002] d..2 14594.229676: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=x ==> next_comm=swapper/2 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229676: tracing_mark_write: B|625|doTransaction
- <...>-2007 (-----) [006] d..2 14594.229688: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229703: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229725: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229750: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229772: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.229792: tracing_mark_write: B|625|doTransaction
- <...>-791 (-----) [000] d..2 14594.229811: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229824: tracing_mark_write: B|625|doTransaction
- <...>-2738 (-----) [007] ...1 14594.229827: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
- <...>-13917 (-----) [001] d..2 14594.229836: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-2738 (-----) [007] ...1 14594.229837: tracing_mark_write: B|2007|setSurfaceDamage
- <...>-625 (-----) [003] ...1 14594.229850: tracing_mark_write: B|625|doTransaction
- <...>-13918 (-----) [002] d..2 14594.229856: sched_blocked_reason: pid=13917 iowait=0 caller=SyS_madvise+0xd34/0xd3c
- <...>-5281 (-----) [001] d..2 14594.229932: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-89 (-----) [006] d..2 14594.229951: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.229982: tracing_mark_write: B|625|handleMessageInvalidate
- <...>-625 (-----) [003] ...1 14594.229984: tracing_mark_write: B|625|handlePageFlip
- <...>-625 (-----) [003] ...1 14594.230013: tracing_mark_write: B|625|latchBuffer
- <...>-13917 (-----) [000] .... 14594.230015: sched_process_exit: comm=ReferenceQueueD pid=13917 prio=124
- <...>-625 (-----) [003] ...1 14594.230020: tracing_mark_write: B|625|query
- <...>-625 (-----) [003] ...1 14594.230028: tracing_mark_write: B|625|updateTexImage
- <...>-625 (-----) [003] ...1 14594.230035: tracing_mark_write: B|625|acquireBuffer
- <...>-625 (-----) [003] ...1 14594.230044: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
- <...>-2738 (-----) [007] d..2 14594.230057: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=D ==> next_comm=smem_native_lpa next_pid=88 next_prio=120
- <...>-14607 (-----) [000] d..2 14594.259609: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-2738 (-----) [005] d..2 14594.259620: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
- <...>-1773 (-----) [005] ...1 14594.259649: tracing_mark_write: B|625|query
- <...>-2738 (-----) [005] ...1 14594.259714: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] d..2 14594.259743: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
- <...>-1773 (-----) [005] ...1 14594.259757: tracing_mark_write: B|625|query
- <...>-2738 (-----) [005] ...1 14594.259810: tracing_mark_write: B|2007|syncFrameState
- <...>-2738 (-----) [005] ...1 14594.259856: tracing_mark_write: B|2007|prepareTree
- Binder:14607_1-14624 (14607) [002] ...1 14594.259863: tracing_mark_write: B|14607|AttachCurrentThread
- Binder:14607_1-14624 (14607) [002] ...1 14594.259869: tracing_mark_write: B|14607|Thread::Attach
- Binder:14607_1-14624 (14607) [002] ...1 14594.259873: tracing_mark_write: B|14607|Thread birth
- Binder:14607_1-14624 (14607) [002] ...1 14594.259916: tracing_mark_write: B|14607|Thread::Init
- Binder:14607_1-14624 (14607) [002] ...1 14594.259920: tracing_mark_write: B|14607|InitStackHwm
- <...>-14607 (-----) [000] d..2 14594.259932: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_1-14624 (14607) [002] d..2 14594.259941: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-3198 (-----) [001] ...1 14594.259942: tracing_mark_write: B|2007|Update SurfaceView position
- Binder:14607_1-14624 (14607) [002] ...1 14594.259963: tracing_mark_write: B|14607|InitTlsEntryPoints
- Binder:14607_1-14624 (14607) [002] ...1 14594.259974: tracing_mark_write: B|14607|InitInterpreterTls
- <...>-14607 (-----) [000] d..2 14594.260005: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-3198 (-----) [001] d..2 14594.260007: sched_switch: prev_comm=hwuiTask1 prev_pid=3198 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-14607 (-----) [000] d..2 14594.260024: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_1-14624 (14607) [002] d..2 14594.260038: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260064: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- Binder:14607_1-14624 (14607) [002] ...1 14594.260101: tracing_mark_write: B|14607|ThreadList::Register
- <...>-2738 (-----) [005] ...1 14594.260128: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260140: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260148: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260155: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260161: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260167: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260173: tracing_mark_write: B|2007|dequeueBuffer
- <...>-2007 (-----) [001] d..2 14594.260201: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-2738 (-----) [005] d..2 14594.260214: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
- <...>-1773 (-----) [005] ...1 14594.260236: tracing_mark_write: B|625|dequeueBuffer
- <...>-1773 (-----) [005] ...1 14594.260249: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
- <...>-14607 (-----) [000] d..2 14594.260334: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_1-14624 (14607) [002] d..2 14594.260343: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260376: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] d..2 14594.260387: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-2738 (-----) [005] ...1 14594.260401: tracing_mark_write: B|2007|HWC release fence 36030 has signaled
- Binder:14607_1-14624 (14607) [002] d..2 14594.260407: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-2738 (-----) [005] ...1 14594.260419: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260427: tracing_mark_write: B|2007|eglBeginFrame
- <...>-2738 (-----) [005] ...1 14594.260445: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [005] ...1 14594.260450: tracing_mark_write: B|2007|query
- Binder:14607_1-14624 (14607) [002] .... 14594.260472: task_newtask: pid=14625 comm=Binder:14607_1 clone_flags=3d0f00 oom_score_adj=-1000
- <...>-14607 (-----) [000] d..2 14594.260517: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260525: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260555: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] ...1 14594.260569: tracing_mark_write: B|14607|ActivityThreadMain
- <...>-14607 (-----) [000] d..2 14594.260581: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260588: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260611: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] d..2 14594.260623: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260636: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260663: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] d..2 14594.260674: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260694: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.260724: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-2738 (-----) [005] ...1 14594.260734: tracing_mark_write: B|2007|flush commands
- <...>-14607 (-----) [000] d..2 14594.260735: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260753: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- Binder:14607_2-14625 (14607) [001] ...1 14594.260925: tracing_mark_write: B|14607|AttachCurrentThread
- Binder:14607_2-14625 (14607) [001] ...1 14594.260930: tracing_mark_write: B|14607|Thread::Attach
- Binder:14607_2-14625 (14607) [001] ...1 14594.260933: tracing_mark_write: B|14607|Thread birth
- Binder:14607_2-14625 (14607) [001] ...1 14594.260973: tracing_mark_write: B|14607|Thread::Init
- Binder:14607_2-14625 (14607) [001] ...1 14594.260977: tracing_mark_write: B|14607|InitStackHwm
- <...>-14607 (-----) [000] d..2 14594.260990: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.260998: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- Binder:14607_2-14625 (14607) [001] ...1 14594.261023: tracing_mark_write: B|14607|InitTlsEntryPoints
- Binder:14607_2-14625 (14607) [001] ...1 14594.261034: tracing_mark_write: B|14607|InitInterpreterTls
- <...>-14607 (-----) [000] d..2 14594.261064: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] d..2 14594.261075: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.261094: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] d..2 14594.261120: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-14607 (-----) [000] d..2 14594.261132: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- Binder:14607_2-14625 (14607) [001] d..2 14594.261146: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- Binder:14607_2-14625 (14607) [001] ...1 14594.261167: tracing_mark_write: B|14607|ThreadList::Register
- <...>-14607 (-----) [000] d..2 14594.261209: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
- <...>-2738 (-----) [005] ...1 14594.261212: tracing_mark_write: B|2007|waitOnFences
- <...>-14607 (-----) [000] d..2 14594.261220: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-2738 (-----) [005] ...1 14594.261232: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
- <...>-2738 (-----) [005] ...1 14594.261244: tracing_mark_write: B|2007|setSurfaceDamage
- Binder:14607_2-14625 (14607) [001] d..2 14594.261246: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
- <...>-14607 (-----) [000] ...1 14594.261326: tracing_mark_write: B|14607|VerifyClass com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
- <...>-2738 (-----) [005] .... 14594.261621: fence_init: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78005
- <...>-625 (-----) [003] ...1 14594.263903: tracing_mark_write: B|625|resetIdleTimer
- <...>-625 (-----) [003] ...1 14594.263912: tracing_mark_write: B|625|rebuildLayerStacks
- <...>-625 (-----) [003] ...1 14594.263915: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
- <...>-625 (-----) [003] ...1 14594.263919: tracing_mark_write: B|625|computeVisibleRegions
- <...>-1398 (-----) [006] d..2 14594.263966: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
- <...>-1695 (-----) [001] d..2 14594.264086: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=120
- <...>-625 (-----) [003] ...1 14594.264293: tracing_mark_write: B|625|calculateWorkingSet
- <...>-625 (-----) [003] ...1 14594.264500: tracing_mark_write: B|625|prepare
- <...>-625 (-----) [003] ...1 14594.264513: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
- <...>-625 (-----) [003] ...2 14594.264584: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
- <...>-625 (-----) [003] d..2 14594.264617: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=logd.writer next_pid=588 next_prio=130
- <...>-588 (-----) [003] d..2 14594.264851: sched_switch: prev_comm=logd.writer prev_pid=588 prev_prio=130 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
- rcu_preempt-7 ( 7) [007] d..2 14594.265273: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:3 next_pid=18008 next_prio=120
- <...>-18008 (-----) [007] d..2 14594.265404: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-18008 (-----) [007] d..2 14594.265471: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.265496: tracing_mark_write: B|625|doComposition
- <...>-625 (-----) [003] ...1 14594.265507: tracing_mark_write: B|625|doComposeSurfaces
- <...>-625 (-----) [003] ...1 14594.265552: tracing_mark_write: B|625|acquireBuffer
- <...>-625 (-----) [003] ...1 14594.265563: tracing_mark_write: B|625|postFramebuffer
- <...>-625 (-----) [003] ...1 14594.265567: tracing_mark_write: B|625|presentAndGetReleaseFences
- <...>-625 (-----) [003] d..1 14594.265601: fence_enable_signal: driver=sde_fence:crtc97:91650 timeline=crtc97 context=3 seqno=91650
- <...>-625 (-----) [003] ...1 14594.265735: tracing_mark_write: B|625|logLayerStats
- <...>-625 (-----) [003] ...1 14594.265744: tracing_mark_write: B|625|postComposition
- <...>-625 (-----) [003] ...1 14594.265749: tracing_mark_write: B|625|releaseBuffer
- <...>-625 (-----) [003] ...1 14594.265753: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
- <...>-625 (-----) [003] ...1 14594.265791: tracing_mark_write: B|625|releaseBuffer
- <...>-440 (-----) [007] d..2 14594.342366: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u17:2 next_pid=1778 next_prio=100
- <...>-2007 (-----) [006] ...1 14594.342375: tracing_mark_write: B|2007|input
- <...>-2007 (-----) [006] ...1 14594.342399: tracing_mark_write: B|2007|animation
- <...>-625 (-----) [003] ...1 14594.342447: tracing_mark_write: B|625|doTransaction
- <...>-625 (-----) [003] ...1 14594.342489: tracing_mark_write: B|625|doTransaction
- kworker/u17:2-1778 ( 1778) [007] d..3 14594.342532: sched_blocked_reason: pid=14607 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
- kworker/u17:2-1778 ( 1778) [007] d..2 14594.342544: sched_switch: prev_comm=kworker/u17:2 prev_pid=1778 prev_prio=100 prev_state=S ==> next_comm=kworker/u16:2 next_pid=27544 next_prio=120
- <...>-1773 (-----) [000] ...1 14594.342575: tracing_mark_write: B|625|requestNextVsync
- <...>-1773 (-----) [000] ...1 14594.342579: tracing_mark_write: B|625|resetIdleTimer
- <...>-27544 (-----) [007] d..2 14594.342589: sched_switch: prev_comm=kworker/u16:2 prev_pid=27544 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-656 (-----) [002] d.h3 14594.342604: sched_blocked_reason: pid=1233 iowait=0 caller=geni_i2c_xfer+0x4d8/0x1398
- <...>-1803 (-----) [001] d..2 14594.342605: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.342632: tracing_mark_write: B|625|handleMessageInvalidate
- <...>-625 (-----) [003] ...1 14594.342634: tracing_mark_write: B|625|handlePageFlip
- <...>-2738 (-----) [007] ...1 14594.342641: tracing_mark_write: B|2007|notifyFramePending
- <...>-658 (-----) [002] d..2 14594.342653: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
- <...>-656 (-----) [002] ...1 14594.342656: tracing_mark_write: B|625|requestNextVsync
- <...>-2738 (-----) [007] d..2 14594.342658: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
- <...>-656 (-----) [002] ...1 14594.342660: tracing_mark_write: B|625|resetIdleTimer
- <...>-660 (-----) [005] d..2 14594.342663: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.342665: tracing_mark_write: B|625|latchBuffer
- <...>-625 (-----) [003] ...1 14594.342673: tracing_mark_write: B|625|query
- <...>-625 (-----) [003] ...1 14594.342682: tracing_mark_write: B|625|updateTexImage
- <...>-625 (-----) [003] ...1 14594.342693: tracing_mark_write: B|625|acquireBuffer
- <...>-625 (-----) [003] ...1 14594.342703: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
- <...>-660 (-----) [005] d..2 14594.342709: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
- <...>-2007 (-----) [006] ...1 14594.342733: tracing_mark_write: B|2007|traversal
- <...>-2007 (-----) [006] ...1 14594.342776: tracing_mark_write: B|2007|draw
- <...>-2007 (-----) [006] ...1 14594.342791: tracing_mark_write: B|2007|Record View#draw()
- <...>-625 (-----) [003] ...1 14594.342849: tracing_mark_write: B|625|updateInputFlinger
- <...>-2007 (-----) [006] d..2 14594.342903: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=kworker/6:2H next_pid=24261 next_prio=100
- <...>-2738 (-----) [007] ...1 14594.342910: tracing_mark_write: B|2007|DrawFrame
- <...>-2738 (-----) [007] d..2 14594.342917: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
- <...>-24261 (-----) [006] d..2 14594.342918: sched_switch: prev_comm=kworker/6:2H prev_pid=24261 prev_prio=100 prev_state=S ==> next_comm=.android.dialer next_pid=14607 next_prio=110
- <...>-440 (-----) [007] d..2 14594.342926: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
- <...>-2738 (-----) [007] ...1 14594.342927: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [007] ...2 14594.342959: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-2738 (-----) [007] d..2 14594.342975: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-656 (-----) [007] ...1 14594.343021: tracing_mark_write: B|625|query
- <...>-656 (-----) [007] .... 14594.343033: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-2738 (-----) [007] ...1 14594.343070: tracing_mark_write: B|2007|query
- <...>-1233 (-----) [004] d..2 14594.343074: sched_switch: prev_comm=sound trigger c prev_pid=1233 prev_prio=120 prev_state=R+ ==> next_comm=irq/144-1436400 next_pid=2522 next_prio=49
- <...>-2738 (-----) [007] ...2 14594.343078: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-625 (-----) [003] ...1 14594.343084: tracing_mark_write: B|625|onMessageReceived
- <...>-625 (-----) [003] ...1 14594.343087: tracing_mark_write: B|625|handleMessageRefresh
- <...>-625 (-----) [003] ...1 14594.343090: tracing_mark_write: B|625|preComposition
- <...>-2738 (-----) [007] d..2 14594.343090: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-625 (-----) [003] ...1 14594.343122: tracing_mark_write: B|625|rebuildLayerStacks
- <...>-625 (-----) [003] ...1 14594.343124: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
- <...>-89 (-----) [007] d..2 14594.343126: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-625 (-----) [003] ...1 14594.343129: tracing_mark_write: B|625|computeVisibleRegions
- <...>-656 (-----) [007] ...1 14594.343136: tracing_mark_write: B|625|query
- <...>-14607 (-----) [006] ...2 14594.343141: binder_set_priority: proc=1368 thread=3253 old=120 => new=110 desired=110
- <...>-2965 (-----) [001] .... 14596.746610: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002ae8fcff pfn=1522884 ofs=188416
- <idle>-0 (-----) [002] d..2 14596.746619: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
- <...>-2965 (-----) [001] .... 14596.746629: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000679ee1ec pfn=1299913 ofs=192512
- <...>-2965 (-----) [001] .... 14596.746664: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000006cd2fb7 pfn=1296251 ofs=196608
- <...>-2965 (-----) [001] .... 14596.746677: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000af82f3d6 pfn=1419330 ofs=200704
- <...>-2965 (-----) [001] .... 14596.746693: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002840f054 pfn=1304928 ofs=204800
- <...>-2965 (-----) [001] .... 14596.746706: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000004a59da17 pfn=1288069 ofs=208896
- <...>-2965 (-----) [001] .... 14596.746717: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000023a80dca pfn=1419686 ofs=212992
- <...>-2965 (-----) [001] .... 14596.746730: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000001cf89eab pfn=1315372 ofs=217088
- <...>-2965 (-----) [001] .... 14596.746743: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000005b4c6cb6 pfn=1380698 ofs=221184
- <...>-2965 (-----) [001] .... 14596.746760: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f8304ae7 pfn=1206753 ofs=225280
- <...>-2965 (-----) [001] .... 14596.746773: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000cb912305 pfn=1325465 ofs=229376
- <...>-2965 (-----) [001] .... 14596.746785: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f16f3774 pfn=1408056 ofs=233472
- <...>-2965 (-----) [001] .... 14596.746801: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000056d4c926 pfn=1418352 ofs=237568
- <...>-2965 (-----) [001] .... 14596.746815: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f3eeb42c pfn=1320957 ofs=241664
- <...>-440 (-----) [002] d..2 14596.746916: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
-
- <...>-656 (-----) [007] .... 14594.343145: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
- <...>-14607 (-----) [006] d..2 14594.343164: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-5281 (-----) [002] d..2 14594.343177: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
- irq/144-1436400-2522 ( 2522) [004] d..2 14594.343223: sched_switch: prev_comm=irq/144-1436400 prev_pid=2522 prev_prio=49 prev_state=D ==> next_comm=sound trigger c next_pid=1233 next_prio=120
- <...>-88 (-----) [006] d..2 14594.343240: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-1238 (-----) [001] d..2 14594.343243: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-2738 (-----) [002] ...1 14594.343244: tracing_mark_write: B|2007|syncFrameState
- <...>-2738 (-----) [002] ...1 14594.343293: tracing_mark_write: B|2007|prepareTree
- <...>-1695 (-----) [001] d..2 14594.343318: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
- <...>-5281 (-----) [005] d..2 14594.343322: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=110
- <...>-1238 (-----) [001] d..2 14594.343442: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=InputDispatcher next_pid=1695 next_prio=112
- <...>-1695 (-----) [001] d..2 14594.343467: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
- <...>-5281 (-----) [000] d..2 14594.343484: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
- <...>-625 (-----) [003] ...1 14594.343519: tracing_mark_write: B|625|calculateWorkingSet
- <...>-2738 (-----) [002] ...1 14594.343568: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343577: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343586: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343591: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343597: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343602: tracing_mark_write: B|2007|query
- <...>-2738 (-----) [002] ...1 14594.343609: tracing_mark_write: B|2007|dequeueBuffer
- <...>-2007 (-----) [006] d..2 14594.343612: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
- <...>-2738 (-----) [002] ...2 14594.343633: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
- <...>-2738 (-----) [002] d..2 14594.343683: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
- <...>-625 (-----) [003] ...1 14594.343704: tracing_mark_write: B|625|prepare
- <...>-656 (-----) [002] ...1 14594.343707: tracing_mark_write: B|625|dequeueBuffer
- <...>-625 (-----) [004] ...1 14594.812869: tracing_mark_write: B|625|com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#0: 2
- <...>-2048 (-----) [000] d..2 14594.812895: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_3 next_pid=1431 next_prio=120
- <...>-1431 (-----) [000] ...1 14594.812911: tracing_mark_write: B|625|query
- <...>-625 (-----) [004] ...1 14594.812914: tracing_mark_write: B|625|latchBuffer
- <...>-625 (-----) [004] ...1 14594.812919: tracing_mark_write: B|625|query
- <...>-625 (-----) [004] ...1 14594.812925: tracing_mark_write: B|625|updateTexImage
- <...>-625 (-----) [004] ...1 14594.812928: tracing_mark_write: B|625|acquireBuffer
- <...>-625 (-----) [004] ...1 14594.812934: tracing_mark_write: B|625|StatusBar#0: 1
- <...>-2048 (-----) [000] ...1 14594.812962: tracing_mark_write: B|1803|syncFrameState
- <...>-656 (-----) [002] ...1 14594.813044: tracing_mark_write: B|625|setTransactionState
- <...>-14607 (-----) [007] ...2 14594.813083: binder_set_priority: proc=10691 thread=18733 old=120 => new=110 desired=110
- <...>-14607 (-----) [007] d..2 14594.813114: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
- <...>-14655 (-----) [006] d..2 14594.813128: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=lpass_smem_glin next_pid=89 next_prio=98
- <...>-89 (-----) [006] d..2 14594.813163: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
- <...>-656 (-----) [002] ...1 14594.813218: tracing_mark_write: B|625|requestNextVsync
- <...>-656 (-----) [002] ...1 14594.813222: tracing_mark_write: B|625|resetIdleTimer
- kworker/7:1-7092 ( 7092) [007] d..2 14594.813239: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
- <...>-5281 (-----) [001] d..2 14594.813245: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
- <...>-88 (-----) [007] d..2 14594.813248: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=R ==> next_comm=kgsl_worker_thr next_pid=259 next_prio=97
- <...>-2048 (-----) [000] d..2 14594.813249: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
- <...>-14655 (-----) [006] d..2 14594.813263: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
- <...>-661 (-----) [002] d..2 14594.813265: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
- <...>-259 (-----) [007] d..2 14594.813265: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
- kworker/7:1-7092 ( 7092) [007] d..2 14594.813271: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
- <...>-108 (-----) [007] .... 14594.813275: ion_heap_shrink: heap_name=system, len=9469952, total_allocated=189620224
- <...>-88 (-----) [006] d..2 14594.813294: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
- <...>-625 (-----) [004] ...1 14594.813310: tracing_mark_write: B|625|updateInputFlinger
- <...>-1238 (-----) [000] d..2 14594.813312: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
- <...>-661 (-----) [002] d..2 14594.813317: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
- <...>-14640 (-----) [005] d..2 14594.813319: sched_switch: prev_comm=DialerExecutors prev_pid=14640 prev_prio=130 prev_state=R ==> next_comm=DispSync next_pid=658 next_prio=97
- <...>-656 (-----) [002] ...1 14594.813336: tracing_mark_write: B|625|~GraphicBuffer
- <...>-658 (-----) [005] d..2 14594.813345: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=DialerExecutors next_pid=14640 next_prio=130
- <...>-656 (-----) [002] ...1 14594.813345: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813353: tracing_mark_write: B|625|~GraphicBuffer
- <...>-2048 (-----) [000] d..2 14594.813358: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
- <...>-656 (-----) [002] ...1 14594.813364: tracing_mark_write: B|625|~GraphicBuffer
- <...>-5281 (-----) [001] d..2 14594.813369: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
- <...>-656 (-----) [002] ...1 14594.813372: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813380: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813391: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813398: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813408: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813416: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813424: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813432: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] .n.1 14594.813443: tracing_mark_write: B|625|~GraphicBuffer
- <...>-1238 (-----) [000] d..2 14594.813464: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
- <...>-5281 (-----) [002] d..2 14594.813525: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
- <...>-656 (-----) [002] ...1 14594.813544: tracing_mark_write: B|625|~GraphicBuffer
- <...>-656 (-----) [002] ...1 14594.813557: tracing_mark_write: B|625|~GraphicBuffer
- <...>-2048 (-----) [000] d..2 14594.813594: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
- <...>-18733 (-----) [001] ...2 14594.813635: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
- <...>-656 (-----) [002] .... 14594.813637: binder_set_priority: proc=625 thread=656 old=116 => new=120 desired=120
- <...>-108 (-----) [007] d..2 14594.813646: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
- <...>-625 (-----) [004] ...1 14594.813646: tracing_mark_write: B|625|onMessageReceived
- <...>-625 (-----) [004] ...1 14594.813649: tracing_mark_write: B|625|handleMessageRefresh
- <...>-625 (-----) [004] ...1 14594.813651: tracing_mark_write: B|625|preComposition
- <...>-625 (-----) [004] ...1 14594.813693: tracing_mark_write: B|625|rebuildLayerStacks
- <...>-625 (-----) [004] ...1 14594.813696: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
- <...>-625 (-----) [004] ...1 14594.813701: tracing_mark_write: B|625|computeVisibleRegions
- <...>-1398 (-----) [007] d..2 14594.813718: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=116 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
- <...>-108 (-----) [007] d..2 14594.813739: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
- <...>-1695 (-----) [002] d..2 14594.813970: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
- <...>-1398 (-----) [007] ...1 14594.814029: tracing_mark_write: B|1368|wmLayout
- <...>-1398 (-----) [007] ...1 14594.814033: tracing_mark_write: B|1368|performSurfacePlacement
- <...>-1398 (-----) [007] ...1 14594.814040: tracing_mark_write: B|1368|applySurfaceChanges
- <...>-1398 (-----) [007] ...1 14594.814043: tracing_mark_write: B|1368|openSurfaceTransaction
- <...>-1398 (-----) [007] ...1 14594.814063: tracing_mark_write: B|1368|performLayout
- <...>-625 (-----) [004] ...1 14594.814119: tracing_mark_write: B|625|calculateWorkingSet
- <...>-1398 (-----) [007] ...1 14594.814241: tracing_mark_write: B|1368|layoutInputConsumer
- <...>-2048 (-----) [000] ...1 14594.814260: tracing_mark_write: B|1803|prepareTree
- <...>-1398 (-----) [007] ...1 14594.814263: tracing_mark_write: B|1368|applyPostLayoutPolicy
- <...>-2048 (-----) [000] d..2 14594.814408: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
- <...>-625 (-----) [004] ...1 14594.814411: tracing_mark_write: B|625|prepare
- <...>-625 (-----) [004] ...1 14594.814428: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
- <...>-2048 (-----) [000] d..2 14594.814533: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
- <...>-1803 (-----) [000] d..2 14594.814558: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
- <...>-2048 (-----) [000] d..2 14594.814572: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
- <...>-625 (-----) [004] ...2 14594.814589: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
- <...>-108 (-----) [002] d..2 14594.814650: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=composer@2.2-se next_pid=627 next_prio=98
- <...>-625 (-----) [004] d..2 14594.814664: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=ashmemd next_pid=854 next_prio=129
- <...>-1398 (-----) [007] ...1 14594.814723: tracing_mark_write: B|1368|applyWindowSurfaceChanges
- <...>-854 (-----) [004] .... 14594.814746: binder_set_priority: proc=854 thread=854 old=129 => new=120 desired=120
- <...>-854 (-----) [004] d..2 14594.814757: sched_switch: prev_comm=ashmemd prev_pid=854 prev_prio=120 prev_state=R+ ==> next_comm=highpool[0] next_pid=3493 next_prio=129
- <...>-1803 (-----) [000] d..2 14594.814763: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
- <...>-18733 (-----) [001] d..1 14594.814819: mm_filemap_delete_from_page_cache: dev 0:1 ino 3ce5e7 page=0000000083f10c7a pfn=1298474 ofs=0
- <...>-2048 (-----) [000] ...1 14594.814842: tracing_mark_write: B|1803|dequeueBuffer
- <...>-1398 (-----) [007] ...1 14594.814850: tracing_mark_write: F|1368|launching: com.google.android.dialer|0
- <...>-1398 (-----) [007] ...1 14594.814855: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunchFinished
- <...>-1398 (-----) [007] ...1 14594.814857: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
- <...>-2048 (-----) [000] d..2 14594.814905: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
- <...>-1410 (-----) [006] .... 14592.997816: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=00000000615a8f24 pfn=1134764 ofs=0
- <...>-1410 (-----) [006] .... 14592.997831: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=000000008768a58f pfn=1134751 ofs=4096
-
- <...>-18733 (-----) [001] .... 14594.814914: binder_set_priority: proc=10691 thread=18733 old=110 => new=120 desired=120
- <...>-14655 (-----) [006] d..2 14594.814932: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=.android.dialer next_pid=14607 next_prio=110
- <...>-656 (-----) [000] ...1 14594.814948: tracing_mark_write: B|625|dequeueBuffer
- <...>-3514 (-----) [001] .... 14594.814954: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
- <...>-656 (-----) [000] ...1 14594.814963: tracing_mark_write: B|625|NavigationBar0#0: 2
- <...>-14607 (-----) [006] ...2 14594.815022: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
- <...>-1398 (-----) [007] ...1 14594.815039: tracing_mark_write: B|1368|prepareSurfaces
- <...>-14607 (-----) [006] d..2 14594.815041: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
- <...>-3493 (-----) [004] d..2 14594.815057: sched_switch: prev_comm=highpool[0] prev_pid=3493 prev_prio=129 prev_state=R ==> next_comm=Binder:1368_18 next_pid=3514 next_prio=110
- <...>-2048 (-----) [000] ...1 14594.815088: tracing_mark_write: B|1803|HWC release fence 45750 has signaled
- <...>-2048 (-----) [000] ...1 14594.815119: tracing_mark_write: B|1803|eglBeginFrame
- <...>-14655 (-----) [006] d..2 14594.815190: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=crtc_commit:97 next_pid=301 next_prio=83
- <...>-3514 (-----) [004] .... 14594.815193: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
- <...>-1398 (-----) [007] ...1 14594.815322: tracing_mark_write: B|1368|closeSurfaceTransaction
- <...>-3493 (-----) [004] .... 14594.815353: mm_filemap_add_to_page_cache: dev 253:6 ino 113b page=0000000069e2b98a pfn=628464 ofs=2723840
- <...>-1398 (-----) [007] ...2 14594.815393: binder_set_priority: proc=625 thread=656 old=120 => new=116 desired=116
- rcu_sched-8 ( 8) [007] d..2 14594.815449: sched_switch: prev_comm=rcu_sched prev_pid=8 prev_prio=120 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
diff --git a/startop/scripts/trace_analyzer/trace_analyzer b/startop/scripts/trace_analyzer/trace_analyzer
deleted file mode 100755
index 8c0396430c40..000000000000
--- a/startop/scripts/trace_analyzer/trace_analyzer
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-# 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.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ "$#" -lt 2 ]]; then
- echo "Usage: $0 <filename.trace> <sqlite-filename.db>" >&2
- exit 1
-fi
-
-TRACE_FILENAME="$1"
-SQLITE_FILENAME="$2"
-
-#echo "Trace filename: $TRACE_FILENAME"
-#echo "SQLite filename: $SQLITE_FILENAME"
-
-if ! [[ -f "$TRACE_FILENAME" ]]; then
- echo "Error: Trace '$TRACE_FILENAME' does not exist." >&2
- exit 1
-fi
-
-if ! "$DIR/trace_analyzer.py" "$SQLITE_FILENAME" "$TRACE_FILENAME" > /dev/null; then
- echo "Fatal: trace_analyzer.py failed, aborting." >&2
- exit 1
-fi
-
-if ! "$DIR/run-sql-queries" "$SQLITE_FILENAME"; then
- echo "Fatal: Failed to run sql queries, aborting." >&2
- exit 1
-fi
diff --git a/startop/scripts/trace_analyzer/trace_analyzer.py b/startop/scripts/trace_analyzer/trace_analyzer.py
deleted file mode 100755
index 62ae018a9986..000000000000
--- a/startop/scripts/trace_analyzer/trace_analyzer.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/python3
-# 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.
-
-import re
-import sys
-import argparse
-
-from lib.trace2db import Trace2Db
-
-# This script requires 'sqlalchemy' to access the sqlite3 database.
-#
-# $> sudo apt-get install python3-pip
-# $> pip3 install --user sqlalchemy
-#
-
-def main(argv):
- parser = argparse.ArgumentParser(description='Convert ftrace/systrace file into sqlite3 db.')
- parser.add_argument('db_filename', metavar='sql_filename.db', type=str,
- help='path to sqlite3 db filename')
- parser.add_argument('trace_filename', metavar='systrace.ftrace', type=str,
- help='path to ftrace/systrace filename')
- parser.add_argument('--limit', type=int, help='limit the number of entries parsed [for debugging]')
-
- args = parser.parse_args()
-
- db_filename = args.db_filename
- trace_filename = args.trace_filename
-
- trace2db = Trace2Db(db_filename)
- print("SQL Alchemy db initialized")
-
- # parse 'raw_ftrace_entries' table
- count = trace2db.parse_file_into_db(trace_filename, limit=args.limit)
- print("Count was ", count)
-
- return 0
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_recursive b/startop/scripts/trace_analyzer/trace_analyzer_recursive
deleted file mode 100755
index 4d9ee0eec9b0..000000000000
--- a/startop/scripts/trace_analyzer/trace_analyzer_recursive
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-# 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.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ "$#" -lt 3 ]]; then
- echo "Usage: $0 <trace-dir> <db-dir> <output.csv>" >&2
- exit 1
-fi
-
-simulate="n"
-
-TRACE_DIRNAME="$1"
-SQLITE_DIRNAME="$2"
-OUTPUT_FILENAME="$3"
-
-echo "Trace filename: $TRACE_DIRNAME"
-echo "SQLite filename: $SQLITE_DIRNAME"
-
-if ! [[ -d "$TRACE_DIRNAME" ]]; then
- echo "Error: Trace '$TRACE_DIRNAME' does not exist." >&2
- exit 1
-fi
-
-process_trace_file() {
- local trace_filename="$1"
- local db_dirname="$2"
- local output_file="$3"
-
- local db_filename="$db_dirname/$(basename "$trace_filename").db"
-
- if [[ $simulate == y ]]; then
- echo "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" "> /dev/null"
- else
- if ! "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" > /dev/null; then
- echo "Fatal: trace_analyzer.py failed, aborting." >&2
- return 1
- fi
- fi
-
- if [[ $simulate == y ]]; then
- echo "$DIR/run-sql-queries" "$db_filename" ">> '$output_file'"
- else
- # append name of trace to CSV, so we can see where data came from
- echo "; $trace_filename" >> "$output_file"
- if ! "$DIR/run-sql-queries" "$db_filename" >> "$output_file"; then
- echo "Fatal: Failed to run sql queries, aborting." >&2
- return 1
- fi
- fi
-
- return 0
-}
-
-find "$TRACE_DIRNAME" -type f -name '*.trace' -print0 |
-while IFS= read -r -d '' file; do
- if [[ $file == *#*.trace && $file != *#1.trace ]]; then
- echo "Skip $file"
- continue
- fi
-
- printf '%s\n' "$file"
- process_trace_file "$file" "$SQLITE_DIRNAME" "$OUTPUT_FILENAME"
-done
-
-echo "Done"
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_test.py b/startop/scripts/trace_analyzer/trace_analyzer_test.py
deleted file mode 100644
index 579529c6f6d5..000000000000
--- a/startop/scripts/trace_analyzer/trace_analyzer_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-#
-
-"""
-Unit tests for trace_analyzer module.
-
-Install:
- $> sudo apt-get install python3-pytest ## OR
- $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
- $> pytest trace_analyzer_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-import os
-import sys
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-
-def test_trace_analyzer(tmpdir):
- # Setup
- bin = os.path.join(DIR, 'trace_analyzer')
- systrace = os.path.join(DIR, 'test_fixtures/common_systrace')
- db_file = tmpdir.mkdir('trace_analyzer').join('test.db')
-
- # Act
- passed, output = cmd_utils.execute_arbitrary_command([bin, systrace,
- str(db_file)],
- timeout=300,
- shell=False,
- simulate=False)
-
- # Assert
- assert passed
- assert output == """\
-'blocked_iowait_duration_ms',\
-'process_name',\
-'launching_duration_ms',\
-'launching_started_timestamp_ms',\
-'launching_finished_timestamp_ms'
-81.697999999960302375,\
-'com.google.android.dialer',\
-594.99400000095192808,\
-14594219.85600000061,\
-14594814.85000000149"""
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index ce9530c196ef..980ea5cd7f8c 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -701,15 +701,8 @@ public final class Call {
*/
public static final int PROPERTY_CROSS_SIM = 0x00004000;
- /**
- * Connection is a tethered external call.
- * Indicates that the {@link Connection} is fixed on this device but the audio streams are
- * re-routed to another device.
- */
- public static final int PROPERTY_TETHERED_CALL = 0x00008000;
-
//******************************************************************************************
- // Next PROPERTY value: 0x00010000
+ // Next PROPERTY value: 0x00004000
//******************************************************************************************
private final @CallState int mState;
@@ -906,9 +899,6 @@ public final class Call {
if (hasProperty(properties, PROPERTY_CROSS_SIM)) {
builder.append(" PROPERTY_CROSS_SIM");
}
- if (hasProperty(properties, PROPERTY_TETHERED_CALL)) {
- builder.append(" PROPERTY_TETHERED_CALL");
- }
builder.append("]");
return builder.toString();
}
@@ -1486,12 +1476,21 @@ public final class Call {
/**
* Invoked when the RTT session failed to initiate for some reason, including rejection
* by the remote party.
+ * <p>
+ * This callback will ONLY be invoked to report a failure related to a user initiated
+ * session modification request (i.e. {@link Call#sendRttRequest()}).
+ * <p>
+ * If a call is initiated with {@link TelecomManager#EXTRA_START_CALL_WITH_RTT} specified,
+ * the availability of RTT can be determined by checking {@link Details#PROPERTY_RTT}
+ * once the call enters state {@link Details#STATE_ACTIVE}.
+ *
* @param call The call which the RTT initiation failure occurred on.
* @param reason One of the status codes defined in
- * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
- * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+ * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
+ * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
*/
- public void onRttInitiationFailure(Call call, int reason) {}
+ public void onRttInitiationFailure(Call call,
+ @android.telecom.Connection.RttModifyStatus.RttSessionModifyStatus int reason) {}
/**
* Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 389df80497df..fccdf76372dd 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -27,6 +27,7 @@ import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -41,8 +42,7 @@ import java.util.stream.Collectors;
public final class CallAudioState implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER,
- ROUTE_EXTERNAL},
+ @IntDef(value={ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER},
flag=true)
public @interface CallAudioRoute {}
@@ -58,9 +58,6 @@ public final class CallAudioState implements Parcelable {
/** Direct the audio stream through the device's speakerphone. */
public static final int ROUTE_SPEAKER = 0x00000008;
- /** Direct the audio stream through another device. */
- public static final int ROUTE_EXTERNAL = 0x00000010;
-
/**
* Direct the audio stream through the device's earpiece or wired headset if one is
* connected.
@@ -73,7 +70,7 @@ public final class CallAudioState implements Parcelable {
* @hide
**/
public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
- ROUTE_SPEAKER | ROUTE_EXTERNAL;
+ ROUTE_SPEAKER;
private final boolean isMuted;
private final int route;
@@ -192,11 +189,7 @@ public final class CallAudioState implements Parcelable {
*/
@CallAudioRoute
public int getSupportedRouteMask() {
- if (route == ROUTE_EXTERNAL) {
- return ROUTE_EXTERNAL;
- } else {
- return supportedRouteMask;
- }
+ return supportedRouteMask;
}
/**
@@ -240,10 +233,6 @@ public final class CallAudioState implements Parcelable {
listAppend(buffer, "SPEAKER");
}
- if ((route & ROUTE_EXTERNAL) == ROUTE_EXTERNAL) {
- listAppend(buffer, "EXTERNAL");
- }
-
return buffer.toString();
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 30d495942ece..6a283df5b480 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -561,15 +561,6 @@ public abstract class Connection extends Conferenceable {
*/
public static final int PROPERTY_CROSS_SIM = 1 << 13;
- /**
- * Connection is a tethered external call.
- * <p>
- * Indicates that the {@link Connection} is fixed on this device but the audio streams are
- * re-routed to another device.
- * <p>
- */
- public static final int PROPERTY_TETHERED_CALL = 1 << 14;
-
//**********************************************************************************************
// Next PROPERTY value: 1<<14
//**********************************************************************************************
@@ -1408,6 +1399,18 @@ public abstract class Connection extends Conferenceable {
* Session modify request rejected by remote user.
*/
public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
+
+
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "SESSION_MODIFY_REQUEST_", value = {
+ SESSION_MODIFY_REQUEST_SUCCESS,
+ SESSION_MODIFY_REQUEST_FAIL,
+ SESSION_MODIFY_REQUEST_INVALID,
+ SESSION_MODIFY_REQUEST_TIMED_OUT,
+ SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE
+ })
+ public @interface RttSessionModifyStatus {}
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 0aaafef492bf..b6cacaf9f289 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1976,7 +1976,7 @@ public class SubscriptionManager {
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
- int slotIndex, int subscriptionType) {
+ int slotIndex, @SubscriptionType int subscriptionType) {
if (VDBG) {
logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
+ ", displayName:" + displayName + ", slotIndex:" + slotIndex
@@ -2012,7 +2012,8 @@ public class SubscriptionManager {
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public void removeSubscriptionInfoRecord(@NonNull String uniqueId, int subscriptionType) {
+ public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
+ @SubscriptionType int subscriptionType) {
if (VDBG) {
logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
+ ", subscriptionType: " + subscriptionType);
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ec734716f6e4..77d4837ccfb6 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -50,12 +50,13 @@ public class DataServiceCallback {
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({RESULT_SUCCESS, RESULT_ERROR_UNSUPPORTED, RESULT_ERROR_INVALID_ARG, RESULT_ERROR_BUSY,
- RESULT_ERROR_ILLEGAL_STATE})
+ RESULT_ERROR_ILLEGAL_STATE, RESULT_ERROR_TEMPORARILY_UNAVAILABLE,
+ RESULT_ERROR_INVALID_RESPONSE})
public @interface ResultCode {}
/** Request is completed successfully */
public static final int RESULT_SUCCESS = 0;
- /** Request is not support */
+ /** Request is not supported */
public static final int RESULT_ERROR_UNSUPPORTED = 1;
/** Request contains invalid arguments */
public static final int RESULT_ERROR_INVALID_ARG = 2;
@@ -68,6 +69,11 @@ public class DataServiceCallback {
* @hide
*/
public static final int RESULT_ERROR_TEMPORARILY_UNAVAILABLE = 5;
+ /**
+ * Request failed to complete due to an invalid response.
+ * @hide
+ */
+ public static final int RESULT_ERROR_INVALID_RESPONSE = 6;
private final IDataServiceCallback mCallback;
@@ -255,6 +261,8 @@ public class DataServiceCallback {
return "RESULT_ERROR_ILLEGAL_STATE";
case RESULT_ERROR_TEMPORARILY_UNAVAILABLE:
return "RESULT_ERROR_TEMPORARILY_UNAVAILABLE";
+ case RESULT_ERROR_INVALID_RESPONSE:
+ return "RESULT_ERROR_INVALID_RESPONSE";
default:
return "Unknown(" + resultCode + ")";
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index b905212a9100..546d2ce0e115 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -424,4 +424,24 @@ public class TelephonyIntents {
*/
@Deprecated
public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
+
+ /**
+ * <p>Broadcast sent to show Emergency notification due to Voice Over Wifi availability
+ *
+ * <p class="note">
+ * You can <em>not</em> receive this through components declared
+ * in manifests, only by explicitly registering for it with
+ * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
+ * android.content.IntentFilter) Context.registerReceiver()}.
+ *
+ * <p class="note">
+ * Requires no permission.
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ *
+ * @hide
+ */
+ public static final String ACTION_VOWIFI_ENABLED
+ = "com.android.internal.telephony.ACTION_VOWIFI_ENABLED";
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index 71e576a2e5ac..7f4966375b98 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -44,7 +44,6 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 219749605)
class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index a9564fdd2332..e7a33543a86b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -46,6 +46,7 @@ import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.common.WindowManagerConditionsFactory
import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -61,8 +62,7 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-@FlakyTest(bugId = 219757170)
-class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
+open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
@@ -72,6 +72,11 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
WindowManagerConditionsFactory.isHomeActivityVisible()
))
+ @Before
+ open fun before() {
+ assumeFalse(isShellTransitionsEnabled)
+ }
+
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
new file mode 100644
index 000000000000..7ffa51320487
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import android.platform.test.annotations.Postsubmit
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group2
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window opening transitions.
+ * To run this test: `atest FlickerTests:ReOpenImeWindowTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group2
+@FlakyTest(bugId = 221854428)
+class ReOpenImeWindowTest_ShellTransit(private val testSpec: FlickerTestParameter)
+ : ReOpenImeWindowTest(testSpec) {
+ @Before
+ override fun before() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ }
+}
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
index 18f962398fb8..bf8bd14645a0 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
@@ -18,11 +18,13 @@ package com.google.android.test.handwritingime;
import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
import android.util.Log;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
+import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
@@ -79,6 +81,14 @@ public class HandwritingIme extends InputMethodService {
view.setPadding(0, 0, 0, 0);
view.addView(inner, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, height));
+ TextView text = new TextView(this);
+ text.setText("Handwriting IME");
+ text.setTextSize(13f);
+ text.setTextColor(getColor(android.R.color.white));
+ text.setGravity(Gravity.CENTER);
+ text.setLayoutParams(new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT, height));
+ view.addView(text);
inner.setBackgroundColor(0xff0110fe); // blue
return view;
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
index 4ffdc9211f1d..87a5b900cc18 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
@@ -33,6 +33,7 @@ class InkView extends View {
private static final long FINISH_TIMEOUT = 2500;
private final HandwritingIme.HandwritingFinisher mHwCanceller;
private final HandwritingIme.StylusConsumer mConsumer;
+ private final int mTopInset;
private Paint mPaint;
private Path mPath;
private float mX, mY;
@@ -63,6 +64,7 @@ class InkView extends View {
setLayoutParams(new ViewGroup.LayoutParams(
metrics.getBounds().width() - insets.left - insets.right,
metrics.getBounds().height() - insets.top - insets.bottom));
+ mTopInset = insets.top;
}
@Override
@@ -74,12 +76,14 @@ class InkView extends View {
}
private void stylusStart(float x, float y) {
+ y = y - mTopInset;
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void stylusMove(float x, float y) {
+ y = y - mTopInset;
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (mPath.isEmpty()) {
diff --git a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
index 06accec09686..ab7f24a8d326 100644
--- a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
+++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
@@ -19,6 +19,9 @@ package com.android.test;
import android.annotation.NonNull;
import android.app.Activity;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -51,6 +54,8 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
private Button mExpandButton;
private Switch mEnableSyncSwitch;
+ private int mLastSyncId = -1;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -71,6 +76,10 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
}
private void updateSurfaceViewSize(Rect bounds, View container) {
+ if (mLastSyncId >= 0) {
+ return;
+ }
+
final float height;
if (mLastExpanded) {
height = bounds.height() / 2f;
@@ -82,13 +91,8 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
mLastExpanded = !mLastExpanded;
if (mEnableSyncSwitch.isChecked()) {
- int syncId = mSurfaceSyncer.setupSync(() -> { });
- mSurfaceSyncer.addToSync(syncId, mSurfaceView, frameCallback ->
- mRenderingThread.setFrameCallback(frameCallback));
- mSurfaceSyncer.addToSync(syncId, container);
- mSurfaceSyncer.markSyncReady(syncId);
- } else {
- mRenderingThread.renderSlow();
+ mLastSyncId = mSurfaceSyncer.setupSync(() -> { });
+ mSurfaceSyncer.addToSync(mLastSyncId, container);
}
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
@@ -99,13 +103,26 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
final Canvas canvas = holder.lockCanvas();
- canvas.drawARGB(255, 100, 100, 100);
+ canvas.drawARGB(255, 255, 0, 0);
holder.unlockCanvasAndPost(canvas);
mRenderingThread.startRendering();
+ mRenderingThread.renderFrame(null, mSurfaceView.getWidth(), mSurfaceView.getHeight());
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+ if (mEnableSyncSwitch.isChecked()) {
+ if (mLastSyncId < 0) {
+ mRenderingThread.renderFrame(null, width, height);
+ return;
+ }
+ mSurfaceSyncer.addToSync(mLastSyncId, mSurfaceView, frameCallback ->
+ mRenderingThread.renderFrame(frameCallback, width, height));
+ mSurfaceSyncer.markSyncReady(mLastSyncId);
+ mLastSyncId = -1;
+ } else {
+ mRenderingThread.renderFrame(null, width, height);
+ }
}
@Override
@@ -117,31 +134,30 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
private final SurfaceHolder mSurfaceHolder;
private Handler mHandler;
private SurfaceSyncer.SurfaceViewFrameCallback mFrameCallback;
- private boolean mRenderSlow;
+ private final Point mSurfaceSize = new Point();
int mColorValue = 0;
int mColorDelta = 10;
+ private final Paint mPaint = new Paint();
RenderingThread(SurfaceHolder holder) {
super("RenderingThread");
mSurfaceHolder = holder;
+ mPaint.setColor(Color.BLACK);
+ mPaint.setTextSize(100);
}
- public void setFrameCallback(SurfaceSyncer.SurfaceViewFrameCallback frameCallback) {
+ public void renderFrame(SurfaceSyncer.SurfaceViewFrameCallback frameCallback, int width,
+ int height) {
if (mHandler != null) {
mHandler.post(() -> {
mFrameCallback = frameCallback;
- mRenderSlow = true;
+ mSurfaceSize.set(width, height);
+ mRunnable.run();
});
}
}
- public void renderSlow() {
- if (mHandler != null) {
- mHandler.post(() -> mRenderSlow = true);
- }
- }
-
private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
@@ -149,13 +165,10 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
mFrameCallback.onFrameStarted();
}
- if (mRenderSlow) {
- try {
- // Long delay from start to finish to mimic slow draw
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- mRenderSlow = false;
+ try {
+ // Long delay from start to finish to mimic slow draw
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
}
mColorValue += mColorDelta;
@@ -164,27 +177,21 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
}
Canvas c = mSurfaceHolder.lockCanvas();
- c.drawRGB(255, mColorValue, 255 - mColorValue);
+ c.drawRGB(255, 0, 0);
+ c.drawText("RENDERED CONTENT", 0, mSurfaceSize.y / 2, mPaint);
mSurfaceHolder.unlockCanvasAndPost(c);
-
- if (mFrameCallback != null) {
- mFrameCallback.onFrameComplete();
- }
mFrameCallback = null;
-
- mHandler.postDelayed(this, 50);
}
};
public void startRendering() {
start();
mHandler = new Handler(getLooper());
- mHandler.post(mRunnable);
}
public void stopRendering() {
if (mHandler != null) {
- mHandler.post(() -> mHandler.removeCallbacks(mRunnable));
+ mHandler.removeCallbacks(mRunnable);
}
}
}
diff --git a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
index c682a00eb8b9..bc100ba03639 100644
--- a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
@@ -59,8 +59,14 @@ class ScreenLockRule : TestRule {
}
private fun verifyKeyguardDismissed() {
- windowManager.dismissKeyguard(null, null)
- Thread.sleep(250)
+ val maxWaits = 30
+ var waitCount = 0
+ while (windowManager.isKeyguardLocked && waitCount < maxWaits) {
+ Log.i(TAG, "Keyguard still showing; attempting to dismiss and wait 50ms ($waitCount)")
+ windowManager.dismissKeyguard(null, null)
+ Thread.sleep(50)
+ waitCount++
+ }
assertWithMessage("Keyguard should be unlocked")
.that(windowManager.isKeyguardLocked)
.isFalse()
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp
index 01eb4f69f842..cc10db9e1523 100644
--- a/tools/aapt/Android.bp
+++ b/tools/aapt/Android.bp
@@ -61,16 +61,6 @@ cc_defaults {
enabled: true,
},
},
-
- // This tool is prebuilt if we're doing an app-only build.
- product_variables: {
- pdk: {
- enabled: false,
- },
- unbundled_build: {
- enabled: false,
- },
- },
}
// ==========================================================
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 42715f9c3592..8d35eeec2a93 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -1038,6 +1038,13 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
continue;
}
+ if (maybe_name.value().substr(0, std::strlen("removed_")) == "removed_") {
+ // Skip resources that have been removed from the framework, but leave a hole so that
+ // other staged resources don't shift and break apps previously compiled against them
+ next_id.id++;
+ continue;
+ }
+
ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
.name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
.source = item_source,
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index 2c2c91825162..0d9ea1b70680 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -243,6 +243,8 @@ def parse_fonts_xml(fonts_xml_path):
name = family.get('name')
variant = family.get('variant')
langs = family.get('lang')
+ ignoreAttr = family.get('ignore')
+
if name:
assert variant is None, (
'No variant expected for LGC font %s.' % name)
@@ -259,6 +261,11 @@ def parse_fonts_xml(fonts_xml_path):
name = family.get('name')
variant = family.get('variant')
langs = family.get('lang')
+ ignoreAttr = family.get('ignore')
+ ignore = ignoreAttr == 'true' or ignoreAttr == '1'
+
+ if ignore:
+ continue
if langs:
langs = langs.split()