summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 01:03:40 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 01:03:40 +0000
commit41bd9e763886576e4817fb9434576a2efbf15dd7 (patch)
treea3796a592456c3df594e66cb90f0009067eab8c9
parent87f04b460e10f76d69e83200a438b54c3a1f444c (diff)
parentf8331a8a91d35383ae0c96b0deeca484144efdd5 (diff)
Snap for 6436225 from f8331a8a91d35383ae0c96b0deeca484144efdd5 to rvc-release
Change-Id: If29135f02904760546d4c364ca80f7033ee18128
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java8
-rw-r--r--api/test-current.txt7
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java12
-rw-r--r--core/java/android/app/Activity.java8
-rw-r--r--core/java/android/app/ITaskStackListener.aidl3
-rw-r--r--core/java/android/app/TaskStackListener.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java16
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--core/java/android/content/pm/LauncherApps.java6
-rw-r--r--core/java/android/content/pm/ShortcutInfo.java6
-rw-r--r--core/java/android/hardware/hdmi/HdmiControlManager.java62
-rw-r--r--core/java/android/hardware/hdmi/IHdmiControlService.aidl2
-rw-r--r--core/java/android/permission/PermissionControllerManager.java3
-rw-r--r--core/java/android/permission/Permissions.md4
-rw-r--r--core/java/android/permission/TEST_MAPPING3
-rwxr-xr-xcore/java/android/provider/Settings.java37
-rw-r--r--core/java/android/view/IWindowManager.aidl8
-rw-r--r--core/java/android/view/InsetsController.java3
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java10
-rw-r--r--core/java/android/view/ViewRootImpl.java29
-rw-r--r--core/java/android/view/WindowManagerGlobal.java4
-rw-r--r--core/java/android/view/WindowManagerImpl.java4
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java5
-rwxr-xr-xcore/java/android/widget/ListPopupWindow.java9
-rw-r--r--core/java/android/window/IWindowOrganizerController.aidl14
-rw-r--r--core/java/android/window/WindowOrganizer.java24
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java15
-rw-r--r--core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java18
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java70
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java22
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java7
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java7
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java15
-rw-r--r--core/java/com/android/internal/policy/DecorContext.java85
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java2
-rw-r--r--core/java/com/android/internal/util/ScreenshotHelper.java147
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java95
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp7
-rw-r--r--core/jni/android_media_AudioRecord.cpp3
-rw-r--r--core/jni/android_media_AudioTrack.cpp3
-rw-r--r--core/res/res/layout/conversation_face_pile_layout.xml2
-rw-r--r--core/res/res/layout/notification_template_header.xml18
-rw-r--r--core/res/res/layout/resolver_list.xml4
-rw-r--r--core/res/res/values-ar/strings.xml4
-rw-r--r--core/res/res/values-hi/strings.xml4
-rw-r--r--core/res/res/values-hy/strings.xml4
-rw-r--r--core/res/res/values/strings.xml17
-rw-r--r--core/res/res/values/styles_device_defaults.xml4
-rw-r--r--core/res/res/values/symbols.xml10
-rw-r--r--core/tests/coretests/src/android/content/ContextTest.java9
-rw-r--r--core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java47
-rw-r--r--core/tests/coretests/src/android/view/InsetsControllerTest.java6
-rw-r--r--core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java6
-rw-r--r--core/tests/coretests/src/android/view/ViewRootImplTest.java12
-rw-r--r--core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java53
-rw-r--r--core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java9
-rw-r--r--graphics/java/android/graphics/BLASTBufferQueue.java9
-rw-r--r--identity/java/android/security/identity/AccessControlProfileId.java2
-rw-r--r--identity/java/android/security/identity/IdentityCredentialStore.java2
-rw-r--r--media/jni/soundpool/Stream.cpp4
-rw-r--r--mime/java-res/android.mime.types2
-rw-r--r--packages/CarSystemUI/res/layout/car_left_navigation_bar.xml1
-rw-r--r--packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml1
-rw-r--r--packages/CarSystemUI/res/layout/car_right_navigation_bar.xml1
-rw-r--r--packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml1
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java55
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java7
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java29
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java2
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java17
-rw-r--r--packages/DynamicSystemInstallationService/res/values/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java7
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java24
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java101
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java17
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java27
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java65
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java6
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java72
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java5
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/res/color/control_foreground.xml2
-rw-r--r--packages/SystemUI/res/color/thermo_cool_foreground.xml2
-rw-r--r--packages/SystemUI/res/color/thermo_heat_foreground.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid_v2.xml1
-rw-r--r--packages/SystemUI/res/layout/hybrid_conversation_notification.xml70
-rw-r--r--packages/SystemUI/res/values-af/strings.xml3
-rw-r--r--packages/SystemUI/res/values-am/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml7
-rw-r--r--packages/SystemUI/res/values-as/strings.xml15
-rw-r--r--packages/SystemUI/res/values-az/strings.xml3
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SystemUI/res/values-be/strings.xml3
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml3
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml15
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml7
-rw-r--r--packages/SystemUI/res/values-da/strings.xml3
-rw-r--r--packages/SystemUI/res/values-el/strings.xml3
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml3
-rw-r--r--packages/SystemUI/res/values-es/strings.xml3
-rw-r--r--packages/SystemUI/res/values-et/strings.xml5
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml3
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml3
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml4
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml3
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml5
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml5
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml3
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml3
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml5
-rw-r--r--packages/SystemUI/res/values-in/strings.xml6
-rw-r--r--packages/SystemUI/res/values-is/strings.xml3
-rw-r--r--packages/SystemUI/res/values-it/strings.xml4
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml3
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-km/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml15
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml3
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml3
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml9
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml15
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml5
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml15
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml3
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml100
-rw-r--r--packages/SystemUI/res/values-or/strings.xml65
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml15
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml5
-rw-r--r--packages/SystemUI/res/values-si/strings.xml3
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml5
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml3
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml6
-rw-r--r--packages/SystemUI/res/values-te/strings.xml15
-rw-r--r--packages/SystemUI/res/values-th/strings.xml3
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml3
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml3
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml15
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml2
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml5
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml3
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml3
-rw-r--r--packages/SystemUI/res/values/colors.xml11
-rw-r--r--packages/SystemUI/res/values/dimens.xml9
-rw-r--r--packages/SystemUI/res/values/styles.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java270
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeService.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java136
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java166
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt51
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java4
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml12
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java7
-rw-r--r--services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java9
-rw-r--r--services/art-profile2
-rw-r--r--services/art-profile-boot1
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java37
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java5
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java2
-rw-r--r--services/core/java/com/android/server/DynamicSystemService.java9
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java13
-rwxr-xr-xservices/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java19
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java5
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java9
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java60
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java2
-rw-r--r--services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java9
-rw-r--r--services/core/java/com/android/server/media/MediaKeyDispatcher.java55
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java188
-rw-r--r--services/core/java/com/android/server/om/OverlayActorEnforcer.java3
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java5
-rw-r--r--services/core/java/com/android/server/om/OverlayableInfoCallback.java4
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java82
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java47
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java18
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java105
-rw-r--r--services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java8
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java262
-rw-r--r--services/core/java/com/android/server/pm/permission/BasePermission.java22
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java43
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java3
-rw-r--r--services/core/java/com/android/server/wm/Dimmer.java4
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java14
-rw-r--r--services/core/java/com/android/server/wm/LocalAnimationAdapter.java10
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java4
-rw-r--r--services/core/java/com/android/server/wm/ShellRoot.java31
-rw-r--r--services/core/java/com/android/server/wm/Task.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioner.java6
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioningController.java19
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java38
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java38
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java31
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java4
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java16
-rw-r--r--services/incremental/IncrementalService.cpp5
-rw-r--r--services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java46
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java112
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java61
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java775
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java83
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java45
-rw-r--r--tools/aapt2/cmd/Link.h4
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp22
-rw-r--r--tools/aapt2/link/ManifestFixer.h4
-rw-r--r--tools/aapt2/link/ManifestFixer_test.cpp26
329 files changed, 4907 insertions, 1950 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 3c1fafbc1495..24728dd8edca 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -110,6 +110,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;
import java.io.File;
@@ -1862,10 +1863,15 @@ public class AppStandbyController implements AppStandbyInternal {
public List<UserHandle> getValidCrossProfileTargets(String pkg, int userId) {
final int uid = mPackageManagerInternal.getPackageUidInternal(pkg, 0, userId);
+ final AndroidPackage aPkg = mPackageManagerInternal.getPackage(uid);
if (uid < 0
- || !mPackageManagerInternal.getPackage(uid).isCrossProfile()
+ || aPkg == null
+ || !aPkg.isCrossProfile()
|| !mCrossProfileAppsInternal
.verifyUidHasInteractAcrossProfilePermission(pkg, uid)) {
+ if (uid >= 0 && aPkg == null) {
+ Slog.wtf(TAG, "Null package retrieved for UID " + uid);
+ }
return Collections.emptyList();
}
return mCrossProfileAppsInternal.getTargetUserProfiles(pkg, userId);
diff --git a/api/test-current.txt b/api/test-current.txt
index d080d3d946c2..5d91adf6c060 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -580,6 +580,7 @@ package android.app.admin {
method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle);
method public boolean isCurrentInputMethodSetByOwner();
method public boolean isDeviceManaged();
+ method public boolean isFactoryResetProtectionPolicySupported();
field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
@@ -2888,8 +2889,10 @@ package android.permission {
public final class PermissionControllerManager {
method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler);
method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler);
method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>);
+ method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String);
method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback);
method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle);
field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1
@@ -2898,6 +2901,10 @@ package android.permission {
field public static final int REASON_MALWARE = 1; // 0x1
}
+ public static interface PermissionControllerManager.OnCountPermissionAppsResultCallback {
+ method public void onCountPermissionApps(int);
+ }
+
public static interface PermissionControllerManager.OnGetAppPermissionResultCallback {
method public void onGetAppPermissions(@NonNull java.util.List<android.permission.RuntimePermissionPresentationInfo>);
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 18e5c3d2d7cc..77b3c81dee85 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -501,6 +501,18 @@ public abstract class AccessibilityService extends Service {
*/
public static final int GLOBAL_ACTION_KEYCODE_HEADSETHOOK = 10;
+ /**
+ * Action to trigger the Accessibility Button
+ * @hide
+ */
+ public static final int GLOBAL_ACTION_ACCESSIBILITY_BUTTON = 11;
+
+ /**
+ * Action to bring up the Accessibility Button's chooser menu
+ * @hide
+ */
+ public static final int GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER = 12;
+
private static final String LOG_TAG = "AccessibilityService";
/**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6480a6abeb78..e0ae750ba5ee 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6549,8 +6549,12 @@ public class Activity extends ContextThemeWrapper
* {@link #RESULT_CANCELED} if the activity explicitly returned that,
* didn't return any result, or crashed during its operation.
*
- * <p>You will receive this call immediately before onResume() when your
- * activity is re-starting.
+ * <p>An activity can never receive a result in the resumed state. You can count on
+ * {@link #onResume} being called after this method, though not necessarily immediately after.
+ * If the activity was resumed, it will be paused and the result will be delivered, followed
+ * by {@link #onResume}. If the activity wasn't in the resumed state, then the result will
+ * be delivered, with {@link #onResume} called sometime later when the activity becomes active
+ * again.
*
* <p>This method is never invoked if your activity sets
* {@link android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 145d5139cdc2..1a619bd4475a 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -43,9 +43,10 @@ oneway interface ITaskStackListener {
* @param homeVisible whether or not the home task is visible
* @param clearedTask whether or not the launch activity also cleared the task as a part of
* starting
+ * @param wasVisible whether the activity was visible before the restart attempt
*/
void onActivityRestartAttempt(in ActivityManager.RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask);
+ boolean clearedTask, boolean wasVisible);
/**
* Called when we launched an activity that we forced to be resizable.
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 93772de0ba30..bfa91aabc6f5 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -55,7 +55,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
@Override
@UnsupportedAppUsage
public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) throws RemoteException {
+ boolean clearedTask, boolean wasVisible) throws RemoteException {
}
@Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 41e2dc0de4d6..4b050455eef2 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10953,6 +10953,22 @@ public class DevicePolicyManager {
}
/**
+ * Returns whether factory reset protection policy is supported on the device.
+ *
+ * @return {@code true} if the device support factory reset protection policy.
+ *
+ * @hide
+ */
+ @TestApi
+ public boolean isFactoryResetProtectionPolicySupported() {
+ try {
+ return mService.isFactoryResetProtectionPolicySupported();
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Called by the device owner or profile owner to clear application user data of a given
* package. The behaviour of this is equivalent to the target application calling
* {@link android.app.ActivityManager#clearApplicationUserData()}.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d10153c11723..9c6a274ccf8c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -108,6 +108,7 @@ interface IDevicePolicyManager {
void setFactoryResetProtectionPolicy(in ComponentName who, in FactoryResetProtectionPolicy policy);
FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(in ComponentName who);
+ boolean isFactoryResetProtectionPolicySupported();
ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList);
ComponentName getGlobalProxyAdmin(int userHandle);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 87dc0a17f41c..bbcac56cf8af 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -507,7 +507,8 @@ public class LauncherApps {
/**
* Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to
* register this callback, have been added or updated.
- * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery)
+ * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery,
+ * Executor)
*
* <p>Only the applications that are allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}, will receive it.
@@ -525,7 +526,8 @@ public class LauncherApps {
/**
* Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to
* register this callback, have been removed.
- * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery)
+ * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery,
+ * Executor)
*
* <p>Only the applications that are allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}, will receive it.
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 8d8776f1bc23..41f9a6e4a274 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -1759,6 +1759,12 @@ public final class ShortcutInfo implements Parcelable {
return isDeclaredInManifest() && isVisibleToPublisher();
}
+ /** @hide */
+ public boolean isNonManifestVisible() {
+ return !isDeclaredInManifest() && isVisibleToPublisher()
+ && (isPinned() || isCached() || isDynamic());
+ }
+
/**
* Return if a shortcut is immutable, in which case it cannot be modified with any of
* {@link ShortcutManager} APIs.
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 65a8e15ba340..6bc962b67576 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -650,6 +650,68 @@ public final class HdmiControlManager {
}
/**
+ * Controls whether volume control commands via HDMI CEC are enabled.
+ *
+ * <p>When disabled:
+ * <ul>
+ * <li>the device will not send any HDMI CEC audio messages
+ * <li>received HDMI CEC audio messages are responded to with {@code <Feature Abort>}
+ * </ul>
+ *
+ * <p>Effects on different device types:
+ * <table>
+ * <tr><th>HDMI CEC device type</th><th>enabled</th><th>disabled</th></tr>
+ * <tr>
+ * <td>TV (type: 0)</td>
+ * <td>Per CEC specification.</td>
+ * <td>TV changes system volume. TV no longer reacts to incoming volume changes via
+ * {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio Status>}
+ * .</td>
+ * </tr>
+ * <tr>
+ * <td>Playback device (type: 4)</td>
+ * <td>Device sends volume commands to TV/Audio system via {@code <User Control
+ * Pressed>}</td><td>Device does not send volume commands via {@code <User Control
+ * Pressed>}.</td>
+ * </tr>
+ * <tr>
+ * <td>Audio device (type: 5)</td>
+ * <td>Full "System Audio Control" capabilities.</td>
+ * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
+ * volume commands. Audio device no longer reports volume changes via {@code <Report
+ * Audio Status>}.</td>
+ * </tr>
+ * </table>
+ *
+ * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
+ *
+ * @param isHdmiCecVolumeControlEnabled target state of HDMI CEC volume control.
+ * @see Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
+ try {
+ mService.setHdmiCecVolumeControlEnabled(isHdmiCecVolumeControlEnabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns whether volume changes via HDMI CEC are enabled.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public boolean isHdmiCecVolumeControlEnabled() {
+ try {
+ return mService.isHdmiCecVolumeControlEnabled();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Gets whether the system is in system audio mode.
*
* @hide
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index a8fed2b03cfc..3582a927ff46 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -80,6 +80,8 @@ interface IHdmiControlService {
void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
void setStandbyMode(boolean isStandbyModeOn);
+ void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled);
+ boolean isHdmiCecVolumeControlEnabled();
void reportAudioStatus(int deviceType, int volume, int maxVolume, boolean isMute);
void setSystemAudioModeOnForAudioOnlySource();
}
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index f08e3d25632b..ed429dd835c3 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -161,6 +161,7 @@ public final class PermissionControllerManager {
*
* @hide
*/
+ @TestApi
public interface OnCountPermissionAppsResultCallback {
/**
* The result for {@link #countPermissionApps(List, int,
@@ -514,6 +515,7 @@ public final class PermissionControllerManager {
*
* @hide
*/
+ @TestApi
@RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
public void revokeRuntimePermission(@NonNull String packageName,
@NonNull String permissionName) {
@@ -534,6 +536,7 @@ public final class PermissionControllerManager {
*
* @hide
*/
+ @TestApi
@RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
public void countPermissionApps(@NonNull List<String> permissionNames,
@CountPermissionAppsFlag int flags,
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index e116dc6f37a1..2bf08e2ff2d4 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -728,7 +728,7 @@ platforms manifest using the `appop` protection level
Almost always the protection level is app-op | something else, like
[signature](#signature-permissions) (in the case above) or [privileged](#privileged-permissions).
-#### Checking a app-op permission
+#### Checking an app-op permission
The `PermissionChecker` utility can check app-op permissions with the [same syntax as runtime
permissions](#checking-a-runtime-permission).
@@ -764,7 +764,7 @@ class PermissionChecker {
}
```
-#### Granting a app-op permission
+#### Granting an app-op permission
The permission's grant state is only considered if the app-op's mode is `MODE_DEFAULT`. This
allows to have default grants while still being overridden by the app-op.
diff --git a/core/java/android/permission/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING
index ba9f36a31f2e..69113ef8f946 100644
--- a/core/java/android/permission/TEST_MAPPING
+++ b/core/java/android/permission/TEST_MAPPING
@@ -5,6 +5,9 @@
"options": [
{
"include-filter": "android.permission.cts.PermissionControllerTest"
+ },
+ {
+ "include-filter": "android.permission.cts.RuntimePermissionPresentationInfoTest"
}
]
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ac1998a04016..fbd6cbae47d9 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9614,6 +9614,43 @@ public final class Settings {
*/
public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
+ /**
+ * Controls whether volume control commands via HDMI CEC are enabled. (0 = false, 1 =
+ * true).
+ *
+ * <p>Effects on different device types:
+ * <table>
+ * <tr><th>HDMI CEC device type</th><th>0: disabled</th><th>1: enabled</th></tr>
+ * <tr>
+ * <td>TV (type: 0)</td>
+ * <td>Per CEC specification.</td>
+ * <td>TV changes system volume. TV no longer reacts to incoming volume changes
+ * via {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio
+ * Status>}.</td>
+ * </tr>
+ * <tr>
+ * <td>Playback device (type: 4)</td>
+ * <td>Device sends volume commands to TV/Audio system via {@code <User Control
+ * Pressed>}</td>
+ * <td>Device does not send volume commands via {@code <User Control Pressed>}.</td>
+ * </tr>
+ * <tr>
+ * <td>Audio device (type: 5)</td>
+ * <td>Full "System Audio Control" capabilities.</td>
+ * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
+ * volume commands. Audio device no longer reports volume changes via {@code
+ * <Report Audio Status>}.</td>
+ * </tr>
+ * </table>
+ *
+ * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
+ *
+ * @hide
+ * @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)
+ */
+ public static final String HDMI_CONTROL_VOLUME_CONTROL_ENABLED =
+ "hdmi_control_volume_control_enabled";
+
/**
* Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
* system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index b3b53f029382..58597cf3fb6d 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -161,6 +161,14 @@ interface IWindowManager
SurfaceControl addShellRoot(int displayId, IWindow client, int windowType);
/**
+ * Sets the window token sent to accessibility for a particular shell root. The
+ * displayId and windowType identify which shell-root to update.
+ *
+ * @param target The IWindow that accessibility service interfaces with.
+ */
+ void setShellRootAccessibilityWindow(int displayId, int windowType, IWindow target);
+
+ /**
* Like overridePendingAppTransitionMultiThumb, but uses a future to supply the specs. This is
* used for recents, where generating the thumbnails of the specs takes a non-trivial amount of
* time, so we want to move that off the critical path for starting the new activity.
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 43c7bede38c2..f135328c44fe 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1002,7 +1002,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
}
- private void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) {
+ @VisibleForTesting
+ public void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) {
if (types == 0) {
// nothing to animate.
return;
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index cfceb031539f..3d6da6f71b3f 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -39,7 +39,7 @@ import java.util.Objects;
* {@link SurfaceView#setChildSurfacePackage}.
*/
public class SurfaceControlViewHost {
- private ViewRootImpl mViewRoot;
+ private final ViewRootImpl mViewRoot;
private WindowlessWindowManager mWm;
private SurfaceControl mSurfaceControl;
@@ -226,6 +226,14 @@ public class SurfaceControlViewHost {
}
/**
+ * @return the ViewRootImpl wrapped by this host.
+ * @hide
+ */
+ public IWindow getWindowToken() {
+ return mViewRoot.mWindow;
+ }
+
+ /**
* @hide
*/
@TestApi
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9d275cdcb00f..8b1e6cbdb6ff 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -327,6 +327,8 @@ public final class ViewRootImpl implements ViewParent,
private boolean mForceNextConfigUpdate;
private boolean mUseBLASTAdapter;
+ private boolean mForceDisableBLAST;
+ private boolean mEnableTripleBuffering;
/**
* Signals that compatibility booleans have been initialized according to
@@ -784,7 +786,6 @@ public final class ViewRootImpl implements ViewParent,
loadSystemProperties();
mImeFocusController = new ImeFocusController(this);
- mUseBLASTAdapter = WindowManagerGlobal.useBLAST();
}
public static void addFirstDrawHandler(Runnable callback) {
@@ -925,10 +926,9 @@ public final class ViewRootImpl implements ViewParent,
if (mWindowAttributes.packageName == null) {
mWindowAttributes.packageName = mBasePackageName;
}
- if (mUseBLASTAdapter) {
- mWindowAttributes.privateFlags |=
+ mWindowAttributes.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
- }
+
attrs = mWindowAttributes;
setTag();
@@ -1102,6 +1102,13 @@ public final class ViewRootImpl implements ViewParent,
"Unable to add window -- unknown error code " + res);
}
+ if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) {
+ mUseBLASTAdapter = true;
+ }
+ if ((res & WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING) != 0) {
+ mEnableTripleBuffering = true;
+ }
+
if (view instanceof RootViewSurfaceTaker) {
mInputQueueCallback =
((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
@@ -1414,10 +1421,8 @@ public final class ViewRootImpl implements ViewParent,
}
mWindowAttributes.privateFlags |= compatibleWindowFlag;
- if (mUseBLASTAdapter) {
- mWindowAttributes.privateFlags |=
+ mWindowAttributes.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
- }
if (mWindowAttributes.preservePreviousSurfaceInsets) {
// Restore old surface insets.
@@ -1784,7 +1789,7 @@ public final class ViewRootImpl implements ViewParent,
Surface ret = null;
if (mBlastBufferQueue == null) {
mBlastBufferQueue = new BLASTBufferQueue(
- mBlastSurfaceControl, width, height);
+ mBlastSurfaceControl, width, height, mEnableTripleBuffering);
// We only return the Surface the first time, as otherwise
// it hasn't changed and there is no need to update.
ret = mBlastBufferQueue.getSurface();
@@ -7393,7 +7398,7 @@ public final class ViewRootImpl implements ViewParent,
mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize, mBlastSurfaceControl);
if (mSurfaceControl.isValid()) {
- if (!mUseBLASTAdapter) {
+ if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
} else {
final Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x,
@@ -9760,7 +9765,7 @@ public final class ViewRootImpl implements ViewParent,
* @hide
*/
public SurfaceControl getRenderSurfaceControl() {
- if (mUseBLASTAdapter) {
+ if (useBLAST()) {
return mBlastSurfaceControl;
} else {
return mSurfaceControl;
@@ -9777,11 +9782,11 @@ public final class ViewRootImpl implements ViewParent,
* flag. Needs to be called before addView.
*/
void forceDisableBLAST() {
- mUseBLASTAdapter = false;
+ mForceDisableBLAST = true;
}
boolean useBLAST() {
- return mUseBLASTAdapter;
+ return mUseBLASTAdapter && !mForceDisableBLAST;
}
/**
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 94591eafe72d..8490f2abeffa 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -124,8 +124,10 @@ public final class WindowManagerGlobal {
*/
public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2;
+ public static final int ADD_FLAG_IN_TOUCH_MODE = 0x1;
public static final int ADD_FLAG_APP_VISIBLE = 0x2;
- public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE;
+ public static final int ADD_FLAG_USE_TRIPLE_BUFFERING = 0x4;
+ public static final int ADD_FLAG_USE_BLAST = 0x8;
/**
* Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS}, but as a "hint" when adding the
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 2975d5ee8e1c..28a18da37b3e 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -36,6 +36,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
import java.util.List;
@@ -69,7 +70,8 @@ import java.util.List;
public final class WindowManagerImpl implements WindowManager {
@UnsupportedAppUsage
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
- private final Context mContext;
+ @VisibleForTesting
+ public final Context mContext;
private final Window mParentWindow;
private IBinder mDefaultToken;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 71dd6653f6a6..3cf61098f11c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -645,11 +645,6 @@ public final class InputMethodManager {
@Override
public void setCurrentRootView(ViewRootImpl rootView) {
synchronized (mH) {
- if (mCurRootView != null) {
- // Reset the last served view and restart window focus state of the root view.
- mCurRootView.getImeFocusController().setServedView(null);
- mRestartOnNextWindowFocus = true;
- }
mCurRootView = rootView;
}
}
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 6425cf11ccb3..4311ffbe0e95 100755
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -746,6 +746,15 @@ public class ListPopupWindow implements ShowableListMenu {
}
/**
+ * Remove existing exit transition from PopupWindow and force immediate dismissal.
+ * @hide
+ */
+ public void dismissImmediate() {
+ mPopup.setExitTransition(null);
+ dismiss();
+ }
+
+ /**
* Set a listener to receive a callback when the popup is dismissed.
*
* @param listener Listener that will be notified when the popup is dismissed.
diff --git a/core/java/android/window/IWindowOrganizerController.aidl b/core/java/android/window/IWindowOrganizerController.aidl
index 7f4b26dba479..7e9c783c83c6 100644
--- a/core/java/android/window/IWindowOrganizerController.aidl
+++ b/core/java/android/window/IWindowOrganizerController.aidl
@@ -16,9 +16,12 @@
package android.window;
+import android.view.SurfaceControl;
+
import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.IWindowContainerTransactionCallback;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
/** @hide */
@@ -47,4 +50,15 @@ interface IWindowOrganizerController {
/** @return An interface enabling the management of display area organizers. */
IDisplayAreaOrganizerController getDisplayAreaOrganizerController();
+
+ /**
+ * Take a screenshot of the requested Window token and place the content of the screenshot into
+ * outSurfaceControl. The SurfaceControl will be a child of the token's parent, so it will be
+ * a sibling of the token's window
+ * @param token The token for the WindowContainer that should get a screenshot taken.
+ * @param outSurfaceControl The SurfaceControl where the screenshot will be attached.
+ *
+ * @return true if the screenshot was successful, false otherwise.
+ */
+ boolean takeScreenshot(in WindowContainerToken token, out SurfaceControl outSurfaceControl);
}
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index 457827117f86..ff40ddac134e 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -17,11 +17,13 @@
package android.window;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.app.ActivityTaskManager;
import android.os.RemoteException;
import android.util.Singleton;
+import android.view.SurfaceControl;
/**
* Base class for organizing specific types of windows like Tasks and DisplayAreas
@@ -63,6 +65,28 @@ public class WindowOrganizer {
}
}
+ /**
+ * Take a screenshot for a specified Window
+ * @param token The token for the WindowContainer that should get a screenshot taken.
+ * @return A SurfaceControl where the screenshot will be attached, or null if failed.
+ *
+ * @hide
+ */
+ @Nullable
+ @RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER)
+ public static SurfaceControl takeScreenshot(@NonNull WindowContainerToken token) {
+ try {
+ SurfaceControl surfaceControl = new SurfaceControl();
+ if (getWindowOrganizerController().takeScreenshot(token, surfaceControl)) {
+ return surfaceControl;
+ } else {
+ return null;
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
static IWindowOrganizerController getWindowOrganizerController() {
return IWindowOrganizerControllerSingleton.get();
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index b58dbddab44f..bcb32fb60f47 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -437,6 +437,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView);
emptyStateView.setVisibility(View.VISIBLE);
+ View container = emptyStateView.findViewById(R.id.resolver_empty_state_container);
+ setupContainerPadding(container);
+
TextView title = emptyStateView.findViewById(R.id.resolver_empty_state_title);
title.setText(titleRes);
@@ -463,6 +466,12 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
activeListAdapter.markTabLoaded();
}
+ /**
+ * Sets up the padding of the view containing the empty state screens.
+ * <p>This method is meant to be overridden so that subclasses can customize the padding.
+ */
+ protected void setupContainerPadding(View container) {}
+
private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) {
ProfileDescriptor descriptor = getItem(
userHandleToPageIndex(activeListAdapter.getUserHandle()));
@@ -555,12 +564,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
}
}
- /**
- * Callback called when the button layout has been hidden.
- * <p>This method is meant to be overridden by subclasses.
- */
- protected void onButtonLayoutHidden() { }
-
public interface OnProfileSelectedListener {
/**
* Callback for when the user changes the active tab from personal to work or vice versa.
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index def11379bdd6..986614c0963c 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -53,6 +53,7 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
private final AppPredictor mAppPredictor;
private final Context mContext;
private final Map<ComponentName, Integer> mTargetRanks = new HashMap<>();
+ private final Map<ComponentName, Integer> mTargetScores = new HashMap<>();
private final UserHandle mUser;
private final Intent mIntent;
private final String mReferrerPackage;
@@ -138,6 +139,11 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
// Null value is okay if we have defaulted to the ResolverRankerService.
if (msg.what == RANKER_SERVICE_RESULT && msg.obj != null) {
final List<AppTarget> sortedAppTargets = (List<AppTarget>) msg.obj;
+ if (checkAppTargetRankValid(sortedAppTargets)) {
+ sortedAppTargets.forEach(target -> mTargetScores.put(
+ new ComponentName(target.getPackageName(), target.getClassName()),
+ target.getRank()));
+ }
for (int i = 0; i < sortedAppTargets.size(); i++) {
mTargetRanks.put(new ComponentName(sortedAppTargets.get(i).getPackageName(),
sortedAppTargets.get(i).getClassName()), i);
@@ -147,11 +153,23 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
}
}
+ private boolean checkAppTargetRankValid(List<AppTarget> sortedAppTargets) {
+ for (AppTarget target : sortedAppTargets) {
+ if (target.getRank() != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
float getScore(ComponentName name) {
if (mResolverRankerService != null) {
return mResolverRankerService.getScore(name);
}
+ if (!mTargetScores.isEmpty()) {
+ return mTargetScores.get(name);
+ }
Integer rank = mTargetRanks.get(name);
if (rank == null) {
Log.w(TAG, "Score requested for unknown component.");
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index bdfcda520281..69a4927c9ab1 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -207,9 +207,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
if (mListViewDataChanged) {
if (mAppendDirectShareEnabled) {
appendServiceTargetsWithQuota();
- if (mPendingChooserTargetService.isEmpty()) {
- fillAllServiceTargets();
- }
}
super.notifyDataSetChanged();
}
@@ -493,6 +490,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
pendingChooserTargetServiceConnections) {
ComponentName origComponentName = origTarget != null ? origTarget.getResolvedComponentName()
: !targets.isEmpty() ? targets.get(0).getComponentName() : null;
+ Log.i(TAG,
+ "parkTargetIntoMemory " + origComponentName + ", " + targets.size() + " targets");
mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream()
.map(ChooserActivity.ChooserTargetServiceConnection::getComponentName)
.filter(componentName -> !componentName.equals(origComponentName))
@@ -532,32 +531,56 @@ public class ChooserListAdapter extends ResolverListAdapter {
private void appendServiceTargetsWithQuota() {
int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets();
List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets);
- int appRank = 0;
+ float totalScore = 0f;
+ for (ComponentName component : topComponentNames) {
+ if (!mPendingChooserTargetService.contains(component)
+ && !mParkingDirectShareTargets.containsKey(component)) {
+ continue;
+ }
+ totalScore += super.getScore(component);
+ }
+ boolean shouldWaitPendingService = false;
for (ComponentName component : topComponentNames) {
if (!mPendingChooserTargetService.contains(component)
&& !mParkingDirectShareTargets.containsKey(component)) {
continue;
}
- appRank++;
+ float score = super.getScore(component);
+ int quota = Math.round(maxRankedTargets * score / totalScore);
+ if (mPendingChooserTargetService.contains(component) && quota >= 1) {
+ shouldWaitPendingService = true;
+ }
+ if (!mParkingDirectShareTargets.containsKey(component)) {
+ continue;
+ }
+ // Append targets into direct share row as per quota.
Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem =
mParkingDirectShareTargets.get(component);
- if (parkingTargetsItem != null && parkingTargetsItem.second == 0) {
- List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first;
- int initTargetsQuota = appRank <= maxRankedTargets / 2 ? 2 : 1;
- int insertedNum = 0;
- while (insertedNum < initTargetsQuota && !parkingTargets.isEmpty()) {
- if (!checkDuplicateTarget(parkingTargets.get(0))) {
- mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0));
- mValidServiceTargetsNum++;
- insertedNum++;
- }
- parkingTargets.remove(0);
- }
- mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum));
- if (mShortcutComponents.contains(component)) {
- mNumShortcutResults += insertedNum;
+ List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first;
+ int insertedNum = parkingTargetsItem.second;
+ while (insertedNum < quota && !parkingTargets.isEmpty()) {
+ if (!checkDuplicateTarget(parkingTargets.get(0))) {
+ mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0));
+ mValidServiceTargetsNum++;
+ insertedNum++;
}
+ parkingTargets.remove(0);
+ }
+ Log.i(TAG, " appendServiceTargetsWithQuota component=" + component
+ + " appendNum=" + (insertedNum - parkingTargetsItem.second));
+ if (DEBUG) {
+ Log.d(TAG, " appendServiceTargetsWithQuota component=" + component
+ + " score=" + score
+ + " totalScore=" + totalScore
+ + " quota=" + quota);
+ }
+ if (mShortcutComponents.contains(component)) {
+ mNumShortcutResults += insertedNum - parkingTargetsItem.second;
}
+ mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum));
+ }
+ if (!shouldWaitPendingService) {
+ fillAllServiceTargets();
}
}
@@ -568,6 +591,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
if (mParkingDirectShareTargets.isEmpty()) {
return;
}
+ Log.i(TAG, " fillAllServiceTargets");
int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets();
List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets);
// Append all remaining targets of top recommended components into direct share row.
@@ -581,7 +605,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
if (mShortcutComponents.contains(component)) {
mNumShortcutResults++;
}
- mServiceTargets.add(target);
+ mServiceTargets.add(mValidServiceTargetsNum, target);
+ mValidServiceTargetsNum++;
});
mParkingDirectShareTargets.remove(component);
}
@@ -593,7 +618,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
.forEach(targets -> {
for (ChooserTargetInfo target : targets) {
if (!checkDuplicateTarget(target)) {
- mServiceTargets.add(target);
+ mServiceTargets.add(mValidServiceTargetsNum, target);
+ mValidServiceTargetsNum++;
mNumShortcutResults++;
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 84c833ea5ffe..4ba6ce4e04ce 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1030,6 +1030,10 @@ public class ResolverActivity extends Activity implements
if (isAutolaunching()) {
return;
}
+ if (isIntentPicker()) {
+ ((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter)
+ .setUseLayoutWithDefault(useLayoutWithDefault());
+ }
if (mMultiProfilePagerAdapter.shouldShowEmptyStateScreen(listAdapter)) {
mMultiProfilePagerAdapter.showEmptyResolverListEmptyState(listAdapter);
} else {
@@ -1782,13 +1786,14 @@ public class ResolverActivity extends Activity implements
if (buttonBarDivider != null) {
buttonBarDivider.setVisibility(View.INVISIBLE);
}
- mMultiProfilePagerAdapter.onButtonLayoutHidden();
+ setButtonBarIgnoreOffset(/* ignoreOffset */ false);
return;
}
if (buttonBarDivider != null) {
buttonBarDivider.setVisibility(View.VISIBLE);
}
buttonLayout.setVisibility(View.VISIBLE);
+ setButtonBarIgnoreOffset(/* ignoreOffset */ true);
if (!useLayoutWithDefault()) {
int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0;
@@ -1802,6 +1807,21 @@ public class ResolverActivity extends Activity implements
resetAlwaysOrOnceButtonBar();
}
+ /**
+ * Updates the button bar container {@code ignoreOffset} layout param.
+ * <p>Setting this to {@code true} means that the button bar will be glued to the bottom of
+ * the screen.
+ */
+ private void setButtonBarIgnoreOffset(boolean ignoreOffset) {
+ View buttonBarContainer = findViewById(R.id.button_bar_container);
+ if (buttonBarContainer != null) {
+ ResolverDrawerLayout.LayoutParams layoutParams =
+ (ResolverDrawerLayout.LayoutParams) buttonBarContainer.getLayoutParams();
+ layoutParams.ignoreOffset = ignoreOffset;
+ buttonBarContainer.setLayoutParams(layoutParams);
+ }
+ }
+
private void resetAlwaysOrOnceButtonBar() {
// Disable both buttons initially
setAlwaysButtonEnabled(false, ListView.INVALID_POSITION, false);
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index cee8a923e198..62bddb17db5f 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -154,6 +154,13 @@ public class ResolverListAdapter extends BaseAdapter {
}
/**
+ * Returns the app share score of the given {@code componentName}.
+ */
+ public float getScore(ComponentName componentName) {
+ return mResolverListController.getScore(componentName);
+ }
+
+ /**
* Returns the list of top K component names which have highest
* {@link #getScore(DisplayResolveInfo)}
*/
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 033ac72dda4e..2b59907cf86b 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -378,6 +378,13 @@ public class ResolverListController {
}
/**
+ * Returns the app share score of the given {@code componentName}.
+ */
+ public float getScore(ComponentName componentName) {
+ return mResolverComparator.getScore(componentName);
+ }
+
+ /**
* Returns the list of top K component names which have highest
* {@link #getScore(DisplayResolveInfo)}
*/
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 5e2470ed9651..b4f9f08e3771 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -36,6 +36,7 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
private final ResolverProfileDescriptor[] mItems;
private final boolean mShouldShowNoCrossProfileIntentsEmptyState;
+ private boolean mUseLayoutWithDefault;
ResolverMultiProfilePagerAdapter(Context context,
ResolverListAdapter adapter,
@@ -213,13 +214,15 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
/* subtitleRes */ 0);
}
+ void setUseLayoutWithDefault(boolean useLayoutWithDefault) {
+ mUseLayoutWithDefault = useLayoutWithDefault;
+ }
+
@Override
- protected void onButtonLayoutHidden() {
- View emptyStateContainer = getItem(getCurrentPage()).getEmptyStateView()
- .findViewById(R.id.resolver_empty_state_container);
- emptyStateContainer.setPadding(emptyStateContainer.getPaddingLeft(),
- emptyStateContainer.getPaddingTop(), emptyStateContainer.getPaddingRight(),
- /* bottom */ 0);
+ protected void setupContainerPadding(View container) {
+ int bottom = mUseLayoutWithDefault ? container.getPaddingBottom() : 0;
+ container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
+ container.getPaddingRight(), bottom);
}
class ResolverProfileDescriptor extends ProfileDescriptor {
diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java
index 99b4b5fb7707..51b41198e272 100644
--- a/core/java/com/android/internal/policy/DecorContext.java
+++ b/core/java/com/android/internal/policy/DecorContext.java
@@ -22,8 +22,6 @@ import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.view.ContextThemeWrapper;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.view.contentcapture.ContentCaptureManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -31,8 +29,8 @@ import com.android.internal.annotations.VisibleForTesting;
import java.lang.ref.WeakReference;
/**
- * Context for decor views which can be seeded with pure application context and not depend on the
- * activity, but still provide some of the facilities that Activity has,
+ * Context for decor views which can be seeded with display context and not depend on the activity,
+ * but still provide some of the facilities that Activity has,
* e.g. themes, activity-based resources, etc.
*
* @hide
@@ -40,80 +38,93 @@ import java.lang.ref.WeakReference;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class DecorContext extends ContextThemeWrapper {
private PhoneWindow mPhoneWindow;
- private WindowManager mWindowManager;
- private Resources mActivityResources;
+ private Resources mResources;
private ContentCaptureManager mContentCaptureManager;
- private WeakReference<Context> mActivityContext;
+ private WeakReference<Context> mContext;
- // TODO(b/149928768): Non-activity context can be passed.
@VisibleForTesting
- public DecorContext(Context context, Context activityContext) {
- super(context.createDisplayContext(activityContext.getDisplayNoVerify()), null);
- mActivityContext = new WeakReference<>(activityContext);
- mActivityResources = activityContext.getResources();
+ public DecorContext(Context baseContext, PhoneWindow phoneWindow) {
+ super(null /* base */, null);
+ setPhoneWindow(phoneWindow);
+ final Context displayContext = baseContext.createDisplayContext(
+ // TODO(b/149790106): Non-activity context can be passed.
+ phoneWindow.getContext().getDisplayNoVerify());
+ attachBaseContext(displayContext);
}
void setPhoneWindow(PhoneWindow phoneWindow) {
mPhoneWindow = phoneWindow;
- mWindowManager = null;
+ final Context context = phoneWindow.getContext();
+ mContext = new WeakReference<>(context);
+ mResources = context.getResources();
}
@Override
public Object getSystemService(String name) {
if (Context.WINDOW_SERVICE.equals(name)) {
- if (mWindowManager == null) {
- WindowManagerImpl wm =
- (WindowManagerImpl) super.getSystemService(Context.WINDOW_SERVICE);
- mWindowManager = wm.createLocalWindowManager(mPhoneWindow);
- }
- return mWindowManager;
+ return mPhoneWindow.getWindowManager();
}
+ final Context context = mContext.get();
if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) {
- if (mContentCaptureManager == null) {
- Context activityContext = mActivityContext.get();
- if (activityContext != null) {
- mContentCaptureManager = (ContentCaptureManager) activityContext
- .getSystemService(name);
- }
+ if (context != null && mContentCaptureManager == null) {
+ mContentCaptureManager = (ContentCaptureManager) context.getSystemService(name);
}
return mContentCaptureManager;
}
- return super.getSystemService(name);
+ // TODO(b/154191411): Try to revisit this issue in S.
+ // We use application to get DisplayManager here because ViewRootImpl holds reference of
+ // DisplayManager and implicitly holds reference of mContext, which makes activity cannot
+ // be GC'd even after destroyed if mContext is an activity object.
+ if (Context.DISPLAY_SERVICE.equals(name)) {
+ return super.getSystemService(name);
+ }
+ // LayoutInflater and WallpaperManagerService should also be obtained from visual context
+ // instead of base context.
+ return (context != null) ? context.getSystemService(name) : super.getSystemService(name);
}
@Override
public Resources getResources() {
- Context activityContext = mActivityContext.get();
+ Context context = mContext.get();
// Attempt to update the local cached Resources from the activity context. If the activity
// is no longer around, return the old cached values.
- if (activityContext != null) {
- mActivityResources = activityContext.getResources();
+ if (context != null) {
+ mResources = context.getResources();
}
- return mActivityResources;
+ return mResources;
}
@Override
public AssetManager getAssets() {
- return mActivityResources.getAssets();
+ return mResources.getAssets();
}
@Override
public AutofillOptions getAutofillOptions() {
- Context activityContext = mActivityContext.get();
- if (activityContext != null) {
- return activityContext.getAutofillOptions();
+ Context context = mContext.get();
+ if (context != null) {
+ return context.getAutofillOptions();
}
return null;
}
@Override
public ContentCaptureOptions getContentCaptureOptions() {
- Context activityContext = mActivityContext.get();
- if (activityContext != null) {
- return activityContext.getContentCaptureOptions();
+ Context context = mContext.get();
+ if (context != null) {
+ return context.getContentCaptureOptions();
}
return null;
}
+
+ @Override
+ public boolean isUiContext() {
+ Context context = mContext.get();
+ if (context != null) {
+ return context.isUiContext();
+ }
+ return false;
+ }
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 23ba6530b072..aa75d4010748 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2358,7 +2358,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (applicationContext == null) {
context = getContext();
} else {
- context = new DecorContext(applicationContext, getContext());
+ context = new DecorContext(applicationContext, this);
if (mTheme != -1) {
context.setTheme(mTheme);
}
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index adadc5e20549..49c9302eeb11 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -27,6 +27,9 @@ import java.util.function.Consumer;
public class ScreenshotHelper {
+ public static final int SCREENSHOT_MSG_URI = 1;
+ public static final int SCREENSHOT_MSG_PROCESS_COMPLETE = 2;
+
/**
* Describes a screenshot request (to make it easier to pass data through to the handler).
*/
@@ -135,6 +138,7 @@ public class ScreenshotHelper {
private final int SCREENSHOT_TIMEOUT_MS = 10000;
private final Object mScreenshotLock = new Object();
+ private IBinder mScreenshotService = null;
private ServiceConnection mScreenshotConnection = null;
private final Context mContext;
@@ -251,85 +255,104 @@ public class ScreenshotHelper {
private void takeScreenshot(final int screenshotType, long timeoutMs, @NonNull Handler handler,
ScreenshotRequest screenshotRequest, @Nullable Consumer<Uri> completionConsumer) {
synchronized (mScreenshotLock) {
- if (mScreenshotConnection != null) {
- return;
- }
- final ComponentName serviceComponent = ComponentName.unflattenFromString(
- mContext.getResources().getString(
- com.android.internal.R.string.config_screenshotServiceComponent));
- final Intent serviceIntent = new Intent();
- final Runnable mScreenshotTimeout = new Runnable() {
- @Override
- public void run() {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != null) {
- mContext.unbindService(mScreenshotConnection);
- mScreenshotConnection = null;
- notifyScreenshotError();
- }
- }
- if (completionConsumer != null) {
- completionConsumer.accept(null);
+ final Runnable mScreenshotTimeout = () -> {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ mScreenshotService = null;
+ notifyScreenshotError();
}
}
+ if (completionConsumer != null) {
+ completionConsumer.accept(null);
+ }
};
- serviceIntent.setComponent(serviceComponent);
- ServiceConnection conn = new ServiceConnection() {
+ Message msg = Message.obtain(null, screenshotType, screenshotRequest);
+ final ServiceConnection myConn = mScreenshotConnection;
+ Handler h = new Handler(handler.getLooper()) {
@Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != this) {
- return;
- }
- Messenger messenger = new Messenger(service);
- Message msg = Message.obtain(null, screenshotType, screenshotRequest);
- final ServiceConnection myConn = this;
- Handler h = new Handler(handler.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection == myConn) {
- mContext.unbindService(mScreenshotConnection);
- mScreenshotConnection = null;
- handler.removeCallbacks(mScreenshotTimeout);
- }
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SCREENSHOT_MSG_URI:
+ if (completionConsumer != null) {
+ completionConsumer.accept((Uri) msg.obj);
+ }
+ handler.removeCallbacks(mScreenshotTimeout);
+ break;
+ case SCREENSHOT_MSG_PROCESS_COMPLETE:
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection == myConn) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ mScreenshotService = null;
}
+ }
+ break;
+ }
+ }
+ };
+ msg.replyTo = new Messenger(h);
+
+ if (mScreenshotConnection == null) {
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(
+ mContext.getResources().getString(
+ com.android.internal.R.string.config_screenshotServiceComponent));
+ final Intent serviceIntent = new Intent();
+
+ serviceIntent.setComponent(serviceComponent);
+ ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != this) {
+ return;
+ }
+ mScreenshotService = service;
+ Messenger messenger = new Messenger(mScreenshotService);
+
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't take screenshot: " + e);
if (completionConsumer != null) {
- completionConsumer.accept((Uri) msg.obj);
+ completionConsumer.accept(null);
}
}
- };
- msg.replyTo = new Messenger(h);
+ }
+ }
- try {
- messenger.send(msg);
- } catch (RemoteException e) {
- Log.e(TAG, "Couldn't take screenshot: " + e);
- if (completionConsumer != null) {
- completionConsumer.accept(null);
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ mScreenshotService = null;
+ handler.removeCallbacks(mScreenshotTimeout);
+ notifyScreenshotError();
}
}
}
+ };
+ if (mContext.bindServiceAsUser(serviceIntent, conn,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ UserHandle.CURRENT)) {
+ mScreenshotConnection = conn;
+ handler.postDelayed(mScreenshotTimeout, timeoutMs);
}
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != null) {
- mContext.unbindService(mScreenshotConnection);
- mScreenshotConnection = null;
- handler.removeCallbacks(mScreenshotTimeout);
- notifyScreenshotError();
- }
+ } else {
+ Messenger messenger = new Messenger(mScreenshotService);
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't take screenshot: " + e);
+ if (completionConsumer != null) {
+ completionConsumer.accept(null);
}
}
- };
- if (mContext.bindServiceAsUser(serviceIntent, conn,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
- UserHandle.CURRENT)) {
- mScreenshotConnection = conn;
handler.postDelayed(mScreenshotTimeout, timeoutMs);
}
}
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 26684201019c..297ebb0ad94d 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -35,10 +35,14 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcelable;
+import android.text.Spannable;
+import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.style.StyleSpan;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -109,7 +113,7 @@ public class ConversationLayout extends FrameLayout
private CharSequence mNameReplacement;
private boolean mIsCollapsed;
private ImageResolver mImageResolver;
- private CachingIconView mConversationIcon;
+ private CachingIconView mConversationIconView;
private View mConversationIconContainer;
private int mConversationIconTopPadding;
private int mConversationIconTopPaddingExpandedGroup;
@@ -157,6 +161,7 @@ public class ConversationLayout extends FrameLayout
private ViewGroup mAppOps;
private Rect mAppOpsTouchRect = new Rect();
private float mMinTouchSize;
+ private Icon mConversationIcon;
public ConversationLayout(@NonNull Context context) {
super(context);
@@ -192,7 +197,7 @@ public class ConversationLayout extends FrameLayout
mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
- mConversationIcon = findViewById(R.id.conversation_icon);
+ mConversationIconView = findViewById(R.id.conversation_icon);
mConversationIconContainer = findViewById(R.id.conversation_icon_container);
mIcon = findViewById(R.id.icon);
mAppOps = findViewById(com.android.internal.R.id.app_ops);
@@ -232,7 +237,7 @@ public class ConversationLayout extends FrameLayout
});
// When the conversation icon is gone, hide the whole badge
- mConversationIcon.setOnForceHiddenChangedListener((forceHidden) -> {
+ mConversationIconView.setOnForceHiddenChangedListener((forceHidden) -> {
animateViewForceHidden(mConversationIconBadgeBg, forceHidden);
animateViewForceHidden(mImportanceRingView, forceHidden);
animateViewForceHidden(mIcon, forceHidden);
@@ -463,7 +468,7 @@ public class ConversationLayout extends FrameLayout
CharSequence conversationText = mConversationTitle;
if (mIsOneToOne) {
// Let's resolve the icon / text from the last sender
- mConversationIcon.setVisibility(VISIBLE);
+ mConversationIconView.setVisibility(VISIBLE);
mConversationFacePile.setVisibility(GONE);
CharSequence userKey = getKey(mUser);
for (int i = mGroups.size() - 1; i >= 0; i--) {
@@ -480,17 +485,20 @@ public class ConversationLayout extends FrameLayout
if (avatarIcon == null) {
avatarIcon = createAvatarSymbol(conversationText, "", mLayoutColor);
}
- mConversationIcon.setImageIcon(avatarIcon);
+ mConversationIcon = avatarIcon;
+ mConversationIconView.setImageIcon(mConversationIcon);
break;
}
}
} else {
if (mLargeIcon != null) {
- mConversationIcon.setVisibility(VISIBLE);
+ mConversationIcon = mLargeIcon;
+ mConversationIconView.setVisibility(VISIBLE);
mConversationFacePile.setVisibility(GONE);
- mConversationIcon.setImageIcon(mLargeIcon);
+ mConversationIconView.setImageIcon(mLargeIcon);
} else {
- mConversationIcon.setVisibility(GONE);
+ mConversationIcon = null;
+ mConversationIconView.setVisibility(GONE);
// This will also inflate it!
mConversationFacePile.setVisibility(VISIBLE);
// rebind the value to the inflated view instead of the stub
@@ -561,15 +569,8 @@ public class ConversationLayout extends FrameLayout
mImageMessageContainer.setVisibility(newMessage != null ? VISIBLE : GONE);
}
- private void bindFacePile() {
- // Let's bind the face pile
- ImageView bottomBackground = mConversationFacePile.findViewById(
- R.id.conversation_face_pile_bottom_background);
+ public void bindFacePile(ImageView bottomBackground, ImageView bottomView, ImageView topView) {
applyNotificationBackgroundColor(bottomBackground);
- ImageView bottomView = mConversationFacePile.findViewById(
- R.id.conversation_face_pile_bottom);
- ImageView topView = mConversationFacePile.findViewById(
- R.id.conversation_face_pile_top);
// Let's find the two last conversations:
Icon secondLastIcon = null;
CharSequence lastKey = null;
@@ -601,6 +602,17 @@ public class ConversationLayout extends FrameLayout
secondLastIcon = createAvatarSymbol("", "", mLayoutColor);
}
topView.setImageIcon(secondLastIcon);
+ }
+
+ private void bindFacePile() {
+ ImageView bottomBackground = mConversationFacePile.findViewById(
+ R.id.conversation_face_pile_bottom_background);
+ ImageView bottomView = mConversationFacePile.findViewById(
+ R.id.conversation_face_pile_bottom);
+ ImageView topView = mConversationFacePile.findViewById(
+ R.id.conversation_face_pile_top);
+
+ bindFacePile(bottomBackground, bottomView, topView);
int conversationAvatarSize;
int facepileAvatarSize;
@@ -614,7 +626,7 @@ public class ConversationLayout extends FrameLayout
facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
}
- LayoutParams layoutParams = (LayoutParams) mConversationIcon.getLayoutParams();
+ LayoutParams layoutParams = (LayoutParams) mConversationIconView.getLayoutParams();
layoutParams.width = conversationAvatarSize;
layoutParams.height = conversationAvatarSize;
mConversationFacePile.setLayoutParams(layoutParams);
@@ -664,11 +676,11 @@ public class ConversationLayout extends FrameLayout
layoutParams.setMarginStart(sidemargin);
mConversationIconBadge.setLayoutParams(layoutParams);
- if (mConversationIcon.getVisibility() == VISIBLE) {
- layoutParams = (LayoutParams) mConversationIcon.getLayoutParams();
+ if (mConversationIconView.getVisibility() == VISIBLE) {
+ layoutParams = (LayoutParams) mConversationIconView.getLayoutParams();
layoutParams.width = conversationAvatarSize;
layoutParams.height = conversationAvatarSize;
- mConversationIcon.setLayoutParams(layoutParams);
+ mConversationIconView.setLayoutParams(layoutParams);
}
}
@@ -719,6 +731,10 @@ public class ConversationLayout extends FrameLayout
mConversationTitle = conversationTitle;
}
+ public CharSequence getConversationTitle() {
+ return mConversationText.getText();
+ }
+
private void removeGroups(ArrayList<MessagingGroup> oldGroups) {
int size = oldGroups.size();
for (int i = 0; i < size; i++) {
@@ -1218,4 +1234,43 @@ public class ConversationLayout extends FrameLayout
public void setMessagingClippingDisabled(boolean clippingDisabled) {
mMessagingLinearLayout.setClipBounds(clippingDisabled ? null : mMessagingClipRect);
}
+
+ @Nullable
+ public CharSequence getConversationSenderName() {
+ if (mGroups.isEmpty()) {
+ return null;
+ }
+ final CharSequence name = mGroups.get(mGroups.size() - 1).getSenderName();
+ return getResources().getString(R.string.conversation_single_line_name_display, name);
+ }
+
+ public boolean isOneToOne() {
+ return mIsOneToOne;
+ }
+
+ @Nullable
+ public CharSequence getConversationText() {
+ if (mMessages.isEmpty()) {
+ return null;
+ }
+ final MessagingMessage messagingMessage = mMessages.get(mMessages.size() - 1);
+ final CharSequence text = messagingMessage.getMessage().getText();
+ if (text == null && messagingMessage instanceof MessagingImageMessage) {
+ final String unformatted =
+ getResources().getString(R.string.conversation_single_line_image_placeholder);
+ SpannableString spannableString = new SpannableString(unformatted);
+ spannableString.setSpan(
+ new StyleSpan(Typeface.ITALIC),
+ 0,
+ spannableString.length(),
+ Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ return spannableString;
+ }
+ return text;
+ }
+
+ @Nullable
+ public Icon getConversationIcon() {
+ return mConversationIcon;
+ }
}
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index 185e58160adf..23f4325c0ff1 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -29,9 +29,10 @@
namespace android {
-static jlong nativeCreate(JNIEnv* env, jclass clazz, jlong surfaceControl, jlong width, jlong height) {
+static jlong nativeCreate(JNIEnv* env, jclass clazz, jlong surfaceControl, jlong width, jlong height,
+ jboolean enableTripleBuffering) {
sp<BLASTBufferQueue> queue = new BLASTBufferQueue(
- reinterpret_cast<SurfaceControl*>(surfaceControl), width, height);
+ reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, enableTripleBuffering);
queue->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(queue.get());
}
@@ -59,7 +60,7 @@ static void nativeUpdate(JNIEnv*env, jclass clazz, jlong ptr, jlong surfaceContr
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- { "nativeCreate", "(JJJ)J",
+ { "nativeCreate", "(JJJZ)J",
(void*)nativeCreate },
{ "nativeGetSurface", "(J)Landroid/view/Surface;",
(void*)nativeGetSurface },
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 6cbc5878db61..8d193bfa1dd2 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -307,6 +307,9 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
status);
goto native_init_failure;
}
+ // Set caller name so it can be logged in destructor.
+ // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_JAVA
+ lpRecorder->setCallerName("java");
} else { // end if nativeRecordInJavaObj == 0)
lpRecorder = (AudioRecord*)nativeRecordInJavaObj;
// TODO: We need to find out which members of the Java AudioRecord might need to be
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 13518186376d..5c045b65be22 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -425,6 +425,9 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
ALOGE("Error %d initializing AudioTrack", status);
goto native_init_failure;
}
+ // Set caller name so it can be logged in destructor.
+ // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_JAVA
+ lpTrack->setCallerName("java");
} else { // end if (nativeAudioTrack == 0)
lpTrack = (AudioTrack*)nativeAudioTrack;
// TODO: We need to find out which members of the Java AudioTrack might
diff --git a/core/res/res/layout/conversation_face_pile_layout.xml b/core/res/res/layout/conversation_face_pile_layout.xml
index 528562534aab..95c14d7c6b5a 100644
--- a/core/res/res/layout/conversation_face_pile_layout.xml
+++ b/core/res/res/layout/conversation_face_pile_layout.xml
@@ -12,7 +12,7 @@
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
- ~ limitations under the License
+ ~ limitations underthe License
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index ece59e2abb22..23b8bd34829e 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -24,12 +24,20 @@
android:layout_height="@dimen/notification_header_height"
android:clipChildren="false"
style="?attr/notificationHeaderStyle">
- <com.android.internal.widget.CachingIconView
- android:id="@+id/icon"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:layout_marginEnd="@dimen/notification_header_icon_margin_end"
+ <!-- Wrapper used to expand the width of the "space" containing the icon programmatically -->
+ <FrameLayout
+ android:id="@+id/header_icon_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/icon"
+ android:layout_width="?attr/notificationHeaderIconSize"
+ android:layout_height="?attr/notificationHeaderIconSize"
+ android:layout_marginEnd="@dimen/notification_header_icon_margin_end"
+ android:layout_gravity="center"
/>
+ </FrameLayout>
<TextView
android:id="@+id/app_name_text"
android:layout_width="wrap_content"
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 76ecefc67c22..4d0837f495df 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -113,11 +113,13 @@
</LinearLayout>
</TabHost>
<LinearLayout
+ android:id="@+id/button_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
android:orientation="vertical"
- android:background="?attr/colorBackgroundFloating">
+ android:background="?attr/colorBackgroundFloating"
+ android:layout_ignoreOffset="true">
<View
android:id="@+id/resolver_button_bar_divider"
android:layout_width="match_parent"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d06bc3b51f04..dfd729e1b204 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -724,7 +724,7 @@
</string-array>
<string-array name="emailAddressTypes">
<item msgid="7786349763648997741">"المنزل"</item>
- <item msgid="435564470865989199">"عمل"</item>
+ <item msgid="435564470865989199">"العمل"</item>
<item msgid="4199433197875490373">"آخر"</item>
<item msgid="3233938986670468328">"مخصص"</item>
</string-array>
@@ -778,7 +778,7 @@
<string name="phoneTypeMms" msgid="1799747455131365989">"رسالة وسائط متعددة"</string>
<string name="eventTypeCustom" msgid="3257367158986466481">"مخصص"</string>
<string name="eventTypeBirthday" msgid="7770026752793912283">"عيد ميلاد"</string>
- <string name="eventTypeAnniversary" msgid="4684702412407916888">"الذكرى السنوية"</string>
+ <string name="eventTypeAnniversary" msgid="4684702412407916888">"ذكرى سنوية"</string>
<string name="eventTypeOther" msgid="530671238533887997">"غير ذلك"</string>
<string name="emailTypeCustom" msgid="1809435350482181786">"مخصص"</string>
<string name="emailTypeHome" msgid="1597116303154775999">"المنزل"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5c38284cf150..569b284684bf 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1806,7 +1806,7 @@
<item quantity="other">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
- <item quantity="one">%1$d घंटों के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
+ <item quantity="one">%1$d घंटे के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
<item quantity="other">%1$d घंटों के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
@@ -1822,7 +1822,7 @@
<item quantity="other">%d मिनट के लिए</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
- <item quantity="one">%d घंटों के लिए</item>
+ <item quantity="one">%d घंटे के लिए</item>
<item quantity="other">%d घंटों के लिए</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 1ba41b313030..73c0c0c722ef 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1403,8 +1403,8 @@
<string name="ime_action_default" msgid="8265027027659800121">"Կատարել"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
<string name="create_contact_using" msgid="6200708808003692594">"Ստեղծել կոնտակտ`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
- <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Հետևյալ մեկ կամ ավել հավելվածներ մուտքի թույլտվության հարցում են անում` այժմ և հետագայում ձեր հաշվին մուտք ունենալու համար:"</string>
- <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Ցանկանու՞մ եք թույլատրել այս հարցումը:"</string>
+ <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Հետևյալ մեկ կամ մի քանի հավելվածներին թույլտվություն է անհրաժեշտ՝ այժմ և հետագայում ձեր հաշվի տվյալներն օգտագործելու համար։"</string>
+ <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Թույլատրե՞լ"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"Մուտքի հարցում"</string>
<string name="allow" msgid="6195617008611933762">"Թույլատրել"</string>
<string name="deny" msgid="6632259981847676572">"Մերժել"</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0e40c988164a..cc586bb7ee89 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4410,6 +4410,12 @@
shortcut enabled. [CHAR LIMIT=none] -->
<string name="accessibility_shortcut_off">Don’t turn on</string>
+ <!-- Text for a feature status that is enabled. [CHAR LIMIT=10] -->
+ <string name="accessibility_shortcut_menu_item_status_on">ON</string>
+
+ <!-- Text for a feature status that is disabled. [CHAR LIMIT=10] -->
+ <string name="accessibility_shortcut_menu_item_status_off">OFF</string>
+
<!-- Title for a warning about security implications of enabling an accessibility
service. [CHAR LIMIT=NONE] -->
<string name="accessibility_enable_service_title">Allow
@@ -5431,14 +5437,14 @@
<string name="accessibility_system_action_quick_settings_label">Quick Settings</string>
<!-- Label for opening power dialog action [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_power_dialog_label">Power Dialog</string>
- <!-- Label for toggle split screen action [CHAR LIMIT=NONE] -->
- <string name="accessibility_system_action_toggle_split_screen_label">Toggle Split Screen</string>
<!-- Label for lock screen action [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_lock_screen_label">Lock Screen</string>
<!-- Label for taking screenshot action [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_screenshot_label">Screenshot</string>
- <!-- Label for showing accessibility menu action [CHAR LIMIT=NONE] -->
- <string name="accessibility_system_action_accessibility_menu_label">Accessibility Menu</string>
+ <!-- Label for showing accessibility shortcut action [CHAR LIMIT=NONE] -->
+ <string name="accessibility_system_action_accessibility_button_label">On-screen Accessibility Shortcut</string>
+ <!-- Label for showing accessibility shortcut menu action [CHAR LIMIT=NONE] -->
+ <string name="accessibility_system_action_accessibility_button_chooser_label">On-screen Accessibility Shortcut Chooser</string>
<!-- Accessibility description of caption view -->
<string name="accessibility_freeform_caption">Caption bar of <xliff:g id="app_name">%1$s</xliff:g>.</string>
@@ -5449,6 +5455,9 @@
<!-- The way a conversation name is displayed when single line. The text will be displayed to the end of this text with some spacing -->
<string name="conversation_single_line_name_display"><xliff:g id="sender_name" example="Sara">%1$s</xliff:g>:</string>
+ <!-- Text used when a conversation is displayed in a single-line when the latest message is an image. [CHAR_LIMIT=NONE] -->
+ <string name="conversation_single_line_image_placeholder">sent an image</string>
+
<!-- Conversation Title fallback if the there is no name provided in a 1:1 conversation [CHAR LIMIT=40]-->
<string name="conversation_title_fallback_one_to_one">Conversation</string>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 64768cf4c730..e9ac679ec39c 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -296,6 +296,10 @@ easier.
<style name="TextAppearance.DeviceDefault.Notification.Info" parent="TextAppearance.Material.Notification.Info">
<item name="fontFamily">@string/config_bodyFontFamily</item>
</style>
+ <style name="TextAppearance.DeviceDefault.Notification.Conversation.AppName"
+ parent="@*android:style/TextAppearance.DeviceDefault.Notification.Title">
+ <item name="android:textSize">16sp</item>
+ </style>
<style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Material.Widget">
<item name="fontFamily">@string/config_bodyFontFamily</item>
</style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 431549713f44..da64e7764191 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1598,6 +1598,8 @@
<java-symbol type="style" name="Theme.DeviceDefault.VoiceInteractionSession" />
<java-symbol type="style" name="Pointer" />
<java-symbol type="style" name="LargePointer" />
+ <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Title" />
+ <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Info" />
<java-symbol type="attr" name="mediaRouteButtonStyle" />
<java-symbol type="attr" name="externalRouteEnabledDrawable" />
@@ -3839,7 +3841,8 @@
<java-symbol type="string" name="accessibility_system_action_recents_label" />
<java-symbol type="string" name="accessibility_system_action_screenshot_label" />
<java-symbol type="string" name="accessibility_system_action_toggle_split_screen_label" />
- <java-symbol type="string" name="accessibility_system_action_accessibility_menu_label" />
+ <java-symbol type="string" name="accessibility_system_action_accessibility_button_label" />
+ <java-symbol type="string" name="accessibility_system_action_accessibility_button_chooser_label" />
<java-symbol type="string" name="accessibility_freeform_caption" />
@@ -3874,7 +3877,10 @@
<java-symbol type="array" name="config_defaultImperceptibleKillingExemptionPkgs" />
<java-symbol type="array" name="config_defaultImperceptibleKillingExemptionProcStates" />
+ <java-symbol type="id" name="header_icon_container" />
+ <java-symbol type="attr" name="notificationHeaderTextAppearance" />
<java-symbol type="string" name="conversation_single_line_name_display" />
+ <java-symbol type="string" name="conversation_single_line_image_placeholder" />
<java-symbol type="string" name="conversation_title_fallback_one_to_one" />
<java-symbol type="string" name="conversation_title_fallback_group_chat" />
<java-symbol type="id" name="conversation_icon" />
@@ -3918,6 +3924,7 @@
<java-symbol type="layout" name="conversation_face_pile_layout" />
<java-symbol type="id" name="conversation_unread_count" />
<java-symbol type="string" name="unread_convo_overflow" />
+ <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Conversation.AppName" />
<!-- Intent resolver and share sheet -->
<java-symbol type="string" name="resolver_personal_tab" />
@@ -3934,6 +3941,7 @@
<java-symbol type="id" name="resolver_tab_divider" />
<java-symbol type="id" name="resolver_button_bar_divider" />
<java-symbol type="id" name="resolver_empty_state_container" />
+ <java-symbol type="id" name="button_bar_container" />
<java-symbol type="string" name="resolver_cant_share_with_work_apps" />
<java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" />
<java-symbol type="string" name="resolver_cant_share_with_personal_apps" />
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index f0997a68492b..aab39bf61163 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -24,13 +24,18 @@ import android.app.ActivityThread;
import android.hardware.display.DisplayManager;
import android.os.UserHandle;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ContextTest
+ */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ContextTest {
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 03aba25bf9f7..5c9e3397c6a5 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -23,36 +23,47 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
-import android.view.SurfaceControl.Transaction;
import android.view.WindowManager.BadTokenException;
import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.FlakyTest;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.Spy;
import java.util.ArrayList;
+/**
+ * Test {@link InsetsSourceConsumer} with IME type.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ImeInsetsSourceConsumerTest
+ */
@Presubmit
@FlakyTest(detail = "Promote once confirmed non-flaky")
@RunWith(AndroidJUnit4.class)
public class ImeInsetsSourceConsumerTest {
- Context mContext = InstrumentationRegistry.getTargetContext();
+ Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
ImeInsetsSourceConsumer mImeConsumer;
- InsetsController mController;
+ @Spy InsetsController mController;
SurfaceControl mLeash;
@Before
@@ -67,7 +78,7 @@ public class ImeInsetsSourceConsumerTest {
} catch (BadTokenException e) {
// activity isn't running, we will ignore BadTokenException.
}
- mController = new InsetsController(viewRootImpl);
+ mController = Mockito.spy(new InsetsController(viewRootImpl));
final Rect rect = new Rect(5, 5, 5, 5);
mController.calculateInsets(
false,
@@ -75,8 +86,7 @@ public class ImeInsetsSourceConsumerTest {
new DisplayCutout(
Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
SOFT_INPUT_ADJUST_RESIZE, 0);
- mImeConsumer = new ImeInsetsSourceConsumer(
- new InsetsState(), Transaction::new, mController);
+ mImeConsumer = (ImeInsetsSourceConsumer) mController.getSourceConsumer(ITYPE_IME);
});
}
@@ -100,6 +110,27 @@ public class ImeInsetsSourceConsumerTest {
}
@Test
+ public void testImeRequestedVisibleAwaitingControl() {
+ // Set null control and then request show.
+ mController.onControlsChanged(new InsetsSourceControl[] { null });
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // Request IME visible before control is available.
+ mImeConsumer.onWindowFocusGained();
+ mImeConsumer.applyImeVisibility(true /* setVisible */);
+
+ // set control and verify visibility is applied.
+ InsetsSourceControl control = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
+ mController.onControlsChanged(new InsetsSourceControl[] { control });
+ // IME show animation should be triggered when control becomes available.
+ verify(mController).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */);
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(true) /* fromIme */);
+ });
+ }
+
+ @Test
public void testAreEditorsSimilar() {
EditorInfo info1 = new EditorInfo();
info1.privateImeOptions = "dummy";
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index d432dda4a1be..ade31d8e4173 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -60,8 +60,8 @@ import android.view.animation.LinearInterpolator;
import android.view.test.InsetsModeSession;
import android.widget.TextView;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
@@ -113,7 +113,7 @@ public class InsetsControllerTest {
.setName("testSurface")
.build();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- Context context = InstrumentationRegistry.getTargetContext();
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
// cannot mock ViewRootImpl since it's final.
mViewRoot = new ViewRootImpl(context, context.getDisplayNoVerify());
try {
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 754c6791cade..cc93f9a5b59c 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -17,8 +17,8 @@
package android.view;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
-
import static android.view.WindowInsets.Type.statusBars;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
@@ -37,8 +37,8 @@ import android.view.WindowManager.BadTokenException;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 0d497e113537..ecc3b4f072f9 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -40,9 +40,9 @@ import android.platform.test.annotations.Presubmit;
import android.view.WindowInsets.Side;
import android.view.WindowInsets.Type;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -51,6 +51,12 @@ import org.junit.runner.RunWith;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+/**
+ * Tests for {@link ViewRootImpl}
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ViewRootImplTest
+ */
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -61,7 +67,7 @@ public class ViewRootImplTest {
@Before
public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getContext();
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mViewRootImpl = new ViewRootImplAccessor(
diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
index 3e40466e4b64..02870a53773e 100644
--- a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
@@ -19,20 +19,26 @@ package com.android.internal.policy;
import static android.view.Display.DEFAULT_DISPLAY;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import android.app.Activity;
+import android.app.EmptyActivity;
import android.content.Context;
import android.hardware.display.DisplayManagerGlobal;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.DisplayInfo;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
-
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,17 +52,22 @@ public final class DecorContextTest {
private Context mContext;
private static final int EXTERNAL_DISPLAY = DEFAULT_DISPLAY + 1;
+ @Rule
+ public ActivityTestRule<EmptyActivity> mActivityRule =
+ new ActivityTestRule<>(EmptyActivity.class);
+
@Before
- public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getContext();
+ public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
}
@Test
public void testDecorContextWithDefaultDisplay() {
Display defaultDisplay = new Display(DisplayManagerGlobal.getInstance(), DEFAULT_DISPLAY,
new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
- DecorContext context = new DecorContext(mContext.getApplicationContext(),
- mContext.createDisplayContext(defaultDisplay));
+ final Context defaultDisplayContext = mContext.createDisplayContext(defaultDisplay);
+ final PhoneWindow window = new PhoneWindow(defaultDisplayContext);
+ DecorContext context = new DecorContext(mContext.getApplicationContext(), window);
assertDecorContextDisplay(DEFAULT_DISPLAY, context);
}
@@ -65,8 +76,9 @@ public final class DecorContextTest {
public void testDecorContextWithExternalDisplay() {
Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY,
new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
- DecorContext context = new DecorContext(mContext.getApplicationContext(),
- mContext.createDisplayContext(display));
+ final Context defaultDisplayContext = mContext.createDisplayContext(display);
+ final PhoneWindow window = new PhoneWindow(defaultDisplayContext);
+ DecorContext context = new DecorContext(mContext.getApplicationContext(), window);
assertDecorContextDisplay(EXTERNAL_DISPLAY, context);
}
@@ -76,4 +88,29 @@ public final class DecorContextTest {
Display associatedDisplay = decorContext.getDisplay();
assertEquals(expectedDisplayId, associatedDisplay.getDisplayId());
}
+
+ @Test
+ public void testGetWindowManagerFromVisualDecorContext() throws Throwable {
+ mActivityRule.runOnUiThread(() -> {
+ Activity activity = mActivityRule.getActivity();
+ final DecorContext decorContext = new DecorContext(mContext.getApplicationContext(),
+ (PhoneWindow) activity.getWindow());
+ WindowManagerImpl actualWm = (WindowManagerImpl)
+ decorContext.getSystemService(WindowManager.class);
+ WindowManagerImpl expectedWm = (WindowManagerImpl)
+ activity.getSystemService(WindowManager.class);
+ // Verify that window manager is from activity not application context.
+ assertEquals(expectedWm.mContext, actualWm.mContext);
+ });
+ }
+
+ @Test
+ public void testIsUiContextFromVisualDecorContext() throws Throwable {
+ mActivityRule.runOnUiThread(() -> {
+ Activity activity = mActivityRule.getActivity();
+ final DecorContext decorContext = new DecorContext(mContext.getApplicationContext(),
+ (PhoneWindow) activity.getWindow());
+ assertTrue(decorContext.isUiContext());
+ });
+ }
}
diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
index 2141b815fb3b..7cd2f3b4c2ab 100644
--- a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
+++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
@@ -354,6 +354,15 @@ public class HdmiAudioSystemClientTest {
@Override
public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
}
+
+ @Override
+ public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
+ }
+
+ @Override
+ public boolean isHdmiCecVolumeControlEnabled() {
+ return true;
+ }
}
}
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 8c6a9371d53b..4c7e960eb0a4 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -26,15 +26,17 @@ public final class BLASTBufferQueue {
// Note: This field is accessed by native code.
private long mNativeObject; // BLASTBufferQueue*
- private static native long nativeCreate(long surfaceControl, long width, long height);
+ private static native long nativeCreate(long surfaceControl, long width, long height,
+ boolean tripleBufferingEnabled);
private static native void nativeDestroy(long ptr);
private static native Surface nativeGetSurface(long ptr);
private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height);
/** Create a new connection with the surface flinger. */
- public BLASTBufferQueue(SurfaceControl sc, int width, int height) {
- mNativeObject = nativeCreate(sc.mNativeObject, width, height);
+ public BLASTBufferQueue(SurfaceControl sc, int width, int height,
+ boolean tripleBufferingEnabled) {
+ mNativeObject = nativeCreate(sc.mNativeObject, width, height, tripleBufferingEnabled);
}
public void destroy() {
@@ -64,4 +66,3 @@ public final class BLASTBufferQueue {
}
}
}
-
diff --git a/identity/java/android/security/identity/AccessControlProfileId.java b/identity/java/android/security/identity/AccessControlProfileId.java
index 3d5945065ad7..6caac0a8a065 100644
--- a/identity/java/android/security/identity/AccessControlProfileId.java
+++ b/identity/java/android/security/identity/AccessControlProfileId.java
@@ -25,6 +25,8 @@ public class AccessControlProfileId {
/**
* Constructs a new object holding a numerical identifier.
*
+ * <p>The identifier must be a non-negative number and less than 32.
+ *
* @param id the identifier.
*/
public AccessControlProfileId(int id) {
diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java
index 4f834d2b87b5..3843d9279900 100644
--- a/identity/java/android/security/identity/IdentityCredentialStore.java
+++ b/identity/java/android/security/identity/IdentityCredentialStore.java
@@ -46,7 +46,7 @@ import java.lang.annotation.RetentionPolicy;
* access control profile IDs. Names are strings and values are typed and can be any
* value supported by <a href="http://cbor.io/">CBOR</a>.</li>
*
- * <li>A set of access control profiles, each with a profile ID and a specification
+ * <li>A set of access control profiles (up to 32), each with a profile ID and a specification
* of the conditions which satisfy the profile's requirements.</li>
*
* <li>An asymmetric key pair which is used to authenticate the credential to the Issuing
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 809e81b13a45..e3152d6349aa 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -330,7 +330,9 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
AudioTrack::TRANSFER_DEFAULT,
nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
mStreamManager->getAttributes());
-
+ // Set caller name so it can be logged in destructor.
+ // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
+ newTrack->setCallerName("soundpool");
oldTrack = mAudioTrack;
status = newTrack->initCheck();
if (status != NO_ERROR) {
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
index c1f8b3f0e195..05a2e92ca080 100644
--- a/mime/java-res/android.mime.types
+++ b/mime/java-res/android.mime.types
@@ -72,7 +72,7 @@
?application/x-x509-server-cert crt
?application/x-x509-user-cert crt
-?audio/3gpp 3gpp 3ga
+?audio/3gpp 3ga 3gpp
?audio/aac-adts aac
?audio/ac3 ac3 a52
?audio/amr amr
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
index d0916b518c92..a8c70989253e 100644
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
@@ -33,7 +33,6 @@
android:gravity="top"
android:paddingTop="30dp"
android:layout_weight="1"
- android:background="@drawable/system_bar_background"
android:animateLayoutChanges="true">
<com.android.systemui.car.navigationbar.CarNavigationButton
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
index de5a15068a5c..9e6dd113eeba 100644
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
@@ -33,7 +33,6 @@
android:gravity="top"
android:paddingTop="30dp"
android:layout_weight="1"
- android:background="@drawable/system_bar_background"
android:animateLayoutChanges="true">
<com.android.systemui.car.navigationbar.CarNavigationButton
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
index d386ce3300e6..fd75570e759c 100644
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
@@ -36,7 +36,6 @@
android:gravity="top"
android:paddingTop="30dp"
android:layout_weight="1"
- android:background="@drawable/system_bar_background"
android:animateLayoutChanges="true">
<com.android.systemui.car.navigationbar.CarNavigationButton
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
index de5a15068a5c..9e6dd113eeba 100644
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
@@ -33,7 +33,6 @@
android:gravity="top"
android:paddingTop="30dp"
android:layout_weight="1"
- android:background="@drawable/system_bar_background"
android:animateLayoutChanges="true">
<com.android.systemui.car.navigationbar.CarNavigationButton
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 2b5cab783916..3b643697022d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -19,7 +19,6 @@ package com.android.systemui.car.navigationbar;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.containsType;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
@@ -28,11 +27,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.inputmethodservice.InputMethodService;
-import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
@@ -47,6 +44,7 @@ import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarDeviceProvisionedListener;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -76,6 +74,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
private final AutoHideController mAutoHideController;
private final ButtonSelectionStateListener mButtonSelectionStateListener;
private final Handler mMainHandler;
+ private final Handler mBgHandler;
+ private final IStatusBarService mBarService;
private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy;
private final ButtonSelectionStateController mButtonSelectionStateController;
private final PhoneStatusBarPolicy mIconPolicy;
@@ -84,7 +84,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
private final int mDisplayId;
private StatusBarSignalPolicy mSignalPolicy;
- private IStatusBarService mBarService;
private ActivityManagerWrapper mActivityManagerWrapper;
// If the nav bar should be hidden when the soft keyboard is visible.
@@ -121,6 +120,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
AutoHideController autoHideController,
ButtonSelectionStateListener buttonSelectionStateListener,
@Main Handler mainHandler,
+ @Background Handler bgHandler,
+ IStatusBarService barService,
Lazy<KeyguardStateController> keyguardStateControllerLazy,
ButtonSelectionStateController buttonSelectionStateController,
PhoneStatusBarPolicy iconPolicy,
@@ -135,6 +136,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
mAutoHideController = autoHideController;
mButtonSelectionStateListener = buttonSelectionStateListener;
mMainHandler = mainHandler;
+ mBgHandler = bgHandler;
+ mBarService = barService;
mKeyguardStateControllerLazy = keyguardStateControllerLazy;
mButtonSelectionStateController = buttonSelectionStateController;
mIconPolicy = iconPolicy;
@@ -150,10 +153,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
mBottomNavBarVisible = false;
- // Get bar service.
- mBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-
// Connect into the status bar manager service
mCommandQueue.addCallback(this);
@@ -233,11 +232,15 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener);
- mCarNavigationBarController.connectToHvac();
+ mBgHandler.post(() -> mCarNavigationBarController.connectToHvac());
// Lastly, call to the icon policy to install/update all the icons.
- mIconPolicy.init();
- mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
+ // Must be called on the main thread due to the use of observeForever() in
+ // mIconPolicy.init().
+ mMainHandler.post(() -> {
+ mIconPolicy.init();
+ mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
+ });
}
private void restartNavBarsIfNecessary() {
@@ -349,33 +352,38 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
- WindowManager.LayoutParams.TYPE_STATUS_BAR,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
- lp.token = new Binder();
- lp.gravity = Gravity.TOP;
- lp.setFitInsetsTypes(0 /* types */);
lp.setTitle("TopCarNavigationBar");
- lp.packageName = mContext.getPackageName();
- lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+ lp.setFitInsetsTypes(0);
+ lp.windowAnimations = 0;
+ lp.gravity = Gravity.TOP;
mWindowManager.addView(mTopNavigationBarWindow, lp);
}
if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
mBottomNavBarVisible = true;
+ int height = mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ height,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.setTitle("BottomCarNavigationBar");
+ lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
lp.windowAnimations = 0;
+ lp.gravity = Gravity.BOTTOM;
mWindowManager.addView(mBottomNavigationBarWindow, lp);
}
@@ -392,11 +400,10 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
PixelFormat.TRANSLUCENT);
leftlp.setTitle("LeftCarNavigationBar");
leftlp.windowAnimations = 0;
- leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
leftlp.gravity = Gravity.LEFT;
- leftlp.setFitInsetsTypes(0 /* types */);
mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
}
+
if (mRightNavigationBarWindow != null) {
int width = mResources.getDimensionPixelSize(
R.dimen.car_right_navigation_bar_width);
@@ -410,9 +417,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
PixelFormat.TRANSLUCENT);
rightlp.setTitle("RightCarNavigationBar");
rightlp.windowAnimations = 0;
- rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
rightlp.gravity = Gravity.RIGHT;
- rightlp.setFitInsetsTypes(0 /* types */);
mWindowManager.addView(mRightNavigationBarWindow, rightlp);
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
index 55c11530fc37..9e194fb49d3a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.systemui.R;
@@ -160,8 +159,12 @@ public class CarNavigationBarController {
}
/** Gets the top navigation bar with the appropriate listeners set. */
- @NonNull
+ @Nullable
public CarNavigationBarView getTopBar(boolean isSetUp) {
+ if (!mShowTop) {
+ return null;
+ }
+
mTopView = mNavigationBarViewFactory.getTopBar(isSetUp);
setupBar(mTopView, mTopBarTouchListener, mNotificationsShadeController);
return mTopView;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
index 46a720b88419..20fc1bcd6013 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
@@ -16,10 +16,14 @@
package com.android.systemui.car.navigationbar;
+import static android.view.WindowInsets.Type.systemBars;
+
import android.content.Context;
+import android.graphics.Insets;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowInsets;
import android.widget.LinearLayout;
import com.android.systemui.Dependency;
@@ -44,7 +48,6 @@ public class CarNavigationBarView extends LinearLayout {
// used to wire in open/close gestures for notifications
private OnTouchListener mStatusBarWindowTouchListener;
-
public CarNavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mConsumeTouchWhenPanelOpen = getResources().getBoolean(
@@ -75,6 +78,30 @@ public class CarNavigationBarView extends LinearLayout {
setClickable(true);
}
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
+ applyMargins(windowInsets.getInsets(systemBars()));
+ return windowInsets;
+ }
+
+ private void applyMargins(Insets insets) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ if (child.getLayoutParams() instanceof LayoutParams) {
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.rightMargin != insets.right || lp.leftMargin != insets.left
+ || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) {
+ lp.rightMargin = insets.right;
+ lp.leftMargin = insets.left;
+ lp.topMargin = insets.top;
+ lp.bottomMargin = insets.bottom;
+ child.requestLayout();
+ }
+ }
+ }
+ }
+
// Used to forward touch events even if the touch was initiated from a child component
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java
index 09a462185dac..8d3eb4c2bbee 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java
@@ -53,7 +53,7 @@ public class TopNotificationPanelViewMediator extends NotificationPanelViewMedia
@Override
public void registerListeners() {
super.registerListeners();
- getCarNavigationBarController().registerBottomBarTouchListener(
+ getCarNavigationBarController().registerTopBarTouchListener(
getNotificationPanelViewController().getDragOpenTouchListener());
}
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
index 6620e9d506ab..adf435972e5b 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
@@ -33,6 +33,7 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarDeviceProvisionedController;
@@ -57,6 +58,7 @@ public class CarNavigationBarTest extends SysuiTestCase {
private CarNavigationBar mCarNavigationBar;
private TestableResources mTestableResources;
private Handler mHandler;
+ private Handler mBackgroundHandler;
@Mock
private CarNavigationBarController mCarNavigationBarController;
@@ -69,6 +71,8 @@ public class CarNavigationBarTest extends SysuiTestCase {
@Mock
private ButtonSelectionStateListener mButtonSelectionStateListener;
@Mock
+ private IStatusBarService mBarService;
+ @Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private ButtonSelectionStateController mButtonSelectionStateController;
@@ -82,11 +86,12 @@ public class CarNavigationBarTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mTestableResources = mContext.getOrCreateTestableResources();
mHandler = Handler.getMain();
+ mBackgroundHandler = Handler.createAsync(TestableLooper.get(this).getLooper());
mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(),
mCarNavigationBarController, mWindowManager, mDeviceProvisionedController,
new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
- mHandler, () -> mKeyguardStateController, mButtonSelectionStateController,
- mIconPolicy, mIconController);
+ mHandler, mBackgroundHandler, mBarService, () -> mKeyguardStateController,
+ mButtonSelectionStateController, mIconPolicy, mIconController);
}
@Test
@@ -103,7 +108,7 @@ public class CarNavigationBarTest extends SysuiTestCase {
verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
+ waitForIdleSync(mBackgroundHandler);
verify(mButtonSelectionStateListener).onTaskStackChanged();
}
@@ -123,7 +128,7 @@ public class CarNavigationBarTest extends SysuiTestCase {
verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
+ waitForIdleSync(mBackgroundHandler);
verify(mCarNavigationBarController).showAllKeyguardButtons(false);
}
@@ -142,12 +147,12 @@ public class CarNavigationBarTest extends SysuiTestCase {
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
+ waitForIdleSync(mBackgroundHandler);
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(false);
deviceProvisionedCallbackCaptor.getValue().onUserSetupChanged();
- waitForIdleSync(mHandler);
+ waitForIdleSync(mBackgroundHandler);
verify(mCarNavigationBarController).hideAllKeyguardButtons(true);
}
diff --git a/packages/DynamicSystemInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml
index e124be605cc7..719fc73bd225 100644
--- a/packages/DynamicSystemInstallationService/res/values/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values/strings.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!-- application name [CHAR LIMIT=32] -->
+ <!-- application name [DO NOT TRANSLATE] -->
<string name="app_name">Dynamic System Updates</string>
- <!-- notification channel name [CHAR LIMIT=32] -->
+ <!-- notification channel name [DO NOT TRANSLATE] -->
<string name="notification_channel_name">Dynamic System Updates</string>
- <!-- password page title [CHAR LIMIT=32] -->
+ <!-- password page title [DO NOT TRANSLATE] -->
<string name="keyguard_title">Dynamic System Updates</string>
<!-- password page description [CHAR LIMIT=128] -->
@@ -23,19 +23,19 @@
<!-- Displayed on notification: We are running in Dynamic System [CHAR LIMIT=128] -->
<string name="notification_dynsystem_in_use">Currently running a dynamic system. Restart to use the original Android version.</string>
- <!-- Action on notification: Cancel installation [CHAR LIMIT=16] -->
+ <!-- Action on notification: Cancel installation [CHAR LIMIT=24] -->
<string name="notification_action_cancel">Cancel</string>
- <!-- Action on notification: Discard installation [CHAR LIMIT=16] -->
+ <!-- Action on notification: Discard installation [CHAR LIMIT=24] -->
<string name="notification_action_discard">Discard</string>
- <!-- Action on notification: Restart to Dynamic System [CHAR LIMIT=16] -->
+ <!-- Action on notification: Restart to Dynamic System [CHAR LIMIT=24] -->
<string name="notification_action_reboot_to_dynsystem">Restart</string>
- <!-- Action on notification: Restart to original Android version [CHAR LIMIT=16] -->
+ <!-- Action on notification: Restart to original Android version [CHAR LIMIT=24] -->
<string name="notification_action_reboot_to_origin">Restart</string>
- <!-- Toast when installed Dynamic System is discarded [CHAR LIMIT=64] -->
+ <!-- Toast when installed Dynamic System is discarded [CHAR LIMIT=128] -->
<string name="toast_dynsystem_discarded">Discarded dynamic system</string>
- <!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=64] -->
+ <!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=128] -->
<string name="toast_failed_to_reboot_to_dynsystem">Can\u2019t restart or load dynamic system</string>
<!-- URL of Dynamic System Key Revocation List [DO NOT TRANSLATE] -->
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 1eef0b7ccf04..7e0ff8174b81 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Sal waarskynlik hou tot omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery kan teen <xliff:g id="TIME">%1$s</xliff:g> afloop"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Foon sal dalk binnekort afgaan"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sal dalk binnekort afgaan"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Toestel sal dalk binnekort afgaan"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f8dcb3a68a89..391ceb7a32ea 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"እስከ <xliff:g id="TIME">%1$s</xliff:g> ገደማ መቆየት አለበት"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"እስከ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ባትሪ እስከ <xliff:g id="TIME">%1$s</xliff:g> ድረስ ሊያልቅ ይችላል"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"ከ <xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"ከ <xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"ከ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> የበለጠ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"ከ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> የበለጠ ይቀራል"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ስልኩ በቅርቡ ሊዘጋ ይችላል"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ጡባዊው በቅርቡ ሊዘጋ ይችላል"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"መሣሪያው በቅርቡ ሊዘጋ ይችላል"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index aee506175875..4f1024bd4f4b 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"حتى <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"قد ينفد شحن البطارية قبل <xliff:g id="TIME">%1$s</xliff:g>."</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"سيبقى شحن البطارية أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"سيبقى شحن البطارية أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g>."</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"قد يتم إغلاق الهاتف قريبًا"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"قد يتم إغلاق الجهاز اللوحي قريبًا"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"قد يتم إغلاق الجهاز قريبًا"</string>
@@ -516,7 +512,7 @@
<string name="alarm_template_far" msgid="6382760514842998629">"يوم <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"المدة"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"الطلب في كل مرة"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن توقف الوضع يدويًا"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن يتم إيقاف الوضع"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"للتو"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"مكبر صوت الهاتف"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 40eb00b2396c..738480f5cae8 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> olana qədər"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya <xliff:g id="TIME">%1$s</xliff:g> radələrinə qədər boşala bilər"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Minimum <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Minimum <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tezliklə sönə bilər"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planşet tezliklə sönə bilər"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Cihaz tezliklə sönə bilər"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index e9d314bd28f6..6187f93a81d4 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija će se možda isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 713c7cd8065d..6cca97da0a38 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Зараду хопіць прыблізна да <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Да <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятар разрадзіцца ў <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Засталося больш за <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Засталося больш за <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Тэлефон у хуткім часе выключыцца"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшэт у хуткім часе выключыцца"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Прылада ў хуткім часе выключыцца"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 57456d9a7ca6..c128f3d0a7d8 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерията може да се изтощи до <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Остава(т) по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Остава(т) по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Остава(т) повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Остава(т) повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Възможно е телефонът да се изключи скоро"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Възможно е таблетът да се изключи скоро"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Възможно е устройството да се изключи скоро"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 0a9d260088f1..6f9188d5ac36 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Srednja brzina"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Istekao"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Isključen"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze…"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati otprilike do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index ffa55afd2092..da70d3b04f38 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"És possible que la bateria s\'esgoti a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"És possible que el telèfon s\'apagui aviat"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"És possible que la tauleta s\'apagui aviat"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"És possible que el dispositiu s\'apagui aviat"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 504cc5eef7b5..4d071b091543 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterie se může vybít do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se brzy vypne"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet se brzy vypne"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zařízení se brzy vypne"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 2f929f788a03..ba56d32a6680 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Enheden løber muligvis tør for batteri inden <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen lukker muligvis snart ned"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Denne tablet lukker muligvis snart ned"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheden lukker muligvis snart ned"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index dcfee98eabaf..8744cb1735a9 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que pronto se apague el teléfono"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que pronto se apague la tablet"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que pronto se apague el dispositivo"</string>
@@ -455,7 +451,7 @@
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
- <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string>
+ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápido"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string>
<string name="battery_info_status_not_charging" msgid="8330015078868707899">"Conectado. No se puede cargar en este momento"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index e7a84751ca72..f1540e6dac87 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Puede que se agote la batería sobre las <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que el teléfono se apague pronto"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que el tablet se apague pronto"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que el dispositivo se apague pronto"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index f42111d1989b..206917e0d3c2 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Peaks kestma kuni <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuni <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Aku võib tühjaks saada kell <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Vähem kui <xliff:g id="THRESHOLD">%1$s</xliff:g> jäänud"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Vähem kui <xliff:g id="THRESHOLD">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Rohkem kui <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Rohkem kui <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon võib peagi välja lülituda"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tahvelarvuti võib peagi välja lülituda"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Seade võib peagi välja lülituda"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 85260fe01e26..d2c2ae4dd299 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Ordu honetara arte iraungo du, gutxi gorabehera: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> arte"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baliteke bateria ordu honetan agortzea: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago geratzen dira"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago geratzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago geratzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago geratzen dira"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baliteke telefonoa laster itzaltzea"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baliteke tableta laster itzaltzea"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baliteke gailua laster itzaltzea"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6afa8898d3b1..fba9ae5532f2 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -435,15 +435,11 @@
<string name="power_discharge_by" msgid="4113180890060388350">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) شارژ داشته باشید"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> شارژ داشته باشید"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"تا <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ممکن است باتری در <xliff:g id="TIME">%1$s</xliff:g> تمام شود"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ممکن است باتری <xliff:g id="TIME">%1$s</xliff:g> تمام شود"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ممکن است تلفن به‌زودی خاموش شود"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ممکن است رایانه لوحی به‌زودی خاموش شود"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ممکن است دستگاه به‌زودی خاموش شود"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 9e1fa76341ee..969180f2fd1e 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Varaus loppuu noin <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> saakka"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akku voi loppua <xliff:g id="TIME">%1$s</xliff:g> mennessä"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Puhelin voi sammua pian"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tabletti voi sammua pian"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Laite voi sammua pian"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index bc113cd263e3..51f79baea6bd 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -218,7 +218,7 @@
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Appareils associés"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Actuellement connecté"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Renseignements sur l\'appareil"</string>
- <string name="adb_device_forget" msgid="193072400783068417">"Oublier"</string>
+ <string name="adb_device_forget" msgid="193072400783068417">"Supprimer"</string>
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Empreinte digitale d\'appareil : <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Échec de la connexion"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Vérifiez que <xliff:g id="DEVICE_NAME">%1$s</xliff:g> est connecté au bon réseau"</string>
@@ -435,7 +435,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La pile risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La pile risque d\'être épuisée d\'ici <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c2a8d496d9eb..5e6ee8691377 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Le téléphone va bientôt s\'éteindre"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"La tablette va bientôt s\'éteindre"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"L\'appareil va bientôt s\'éteindre"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 2a6bcfc51c3a..caa1f1bf171e 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -435,15 +435,11 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Ata: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A batería pode esgotarse á seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A batería pode esgotarse a esta hora: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O teléfono pode apagarse en breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"A tableta pode apagarse en breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo pode apagarse en breve"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index f6a237434413..5bfe3a3f9e5f 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"લગભગ <xliff:g id="TIME">%1$s</xliff:g> સુધી ચાલવી જોઈએ"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> સુધી"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"બૅટરી <xliff:g id="TIME">%1$s</xliff:g> સુધીમાં પૂરી થઈ શકે છે"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછી બાકી છે"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછી (<xliff:g id="LEVEL">%2$s</xliff:g>) બાકી છે"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> કરતાં વધુ (<xliff:g id="LEVEL">%2$s</xliff:g>) બાકી છે"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> કરતાં વધુ બાકી છે"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ફોન થોડીક જ વારમાં બંધ થઈ શકે છે"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ટૅબ્લેટ થોડીક જ વારમાં બંધ થઈ શકે છે"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ડિવાઇસ થોડીક જ વારમાં બંધ થઈ શકે છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index b084123da139..999e344812b4 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -161,7 +161,7 @@
<string name="tts_default_pitch_title" msgid="6988592215554485479">"पिच"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"कृत्रिम बोली के लहजे को प्रभावित करता है"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"भाषा"</string>
- <string name="tts_lang_use_system" msgid="6312945299804012406">"सिस्‍टम भाषा का उपयोग करें"</string>
+ <string name="tts_lang_use_system" msgid="6312945299804012406">"सिस्‍टम की भाषा का इस्तेमाल करें"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"भाषा नहीं चुनी गई है"</string>
<string name="tts_default_lang_summary" msgid="9042620014800063470">"बोले गए लेख के लिए भाषा-विशिष्ट ध्‍वनि सेट करता है"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"एक उदाहरण सुनें"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"बैटरी करीब <xliff:g id="TIME">%1$s</xliff:g> तक चलेगी"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> तक"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"बैटरी <xliff:g id="TIME">%1$s</xliff:g> तक खत्म हो जाएगी"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फ़ोन जल्द ही बंद हो सकता है"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"टैबलेट जल्द ही बंद हो सकता है"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"डिवाइस जल्द ही बंद हो सकता है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 115fef8c7b27..391d62c02e40 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon bi se uskoro mogao isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet bi se uskoro mogao isključiti"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj bi se uskoro mogao isključiti"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index a223b4d03b2a..02a7b67c2f6b 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet a következő időpontig: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Előfordulhat, hogy a telefon hamarosan kikapcsol"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Előfordulhat, hogy a táblagép hamarosan kikapcsol"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Előfordulhat, hogy az eszköz hamarosan kikapcsol"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 8d40abc9ab72..8b7679a4b54c 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Լիցքը պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Մարտկոցի լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Հեռախոսը շուտով կանջատվի"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Պլանշետը շուտով կանջատվի"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Սարքը շուտով կանջատվի"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d925df3a8239..543403a66735 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Miðlungshratt"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Hratt"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Mjög hratt"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunninn"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunnin"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Aftengt"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Aftengist…"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Ætti að endast til u.þ.b. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til klukkan <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Rafhlaðan gæti tæmst kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Síminn gæti slökkt á sér fljótlega"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Spjaldtölvan gæti slökkt á sér fljótlega"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Tækið gæti slökkt á sér fljótlega"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 3f385974bb9e..dd597d02005f 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Veloce"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Molto veloce"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduto"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduta"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione..."</string>
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Scegli profilo"</string>
<string name="category_personal" msgid="6236798763159385225">"Personali"</string>
- <string name="category_work" msgid="4014193632325996115">"Lavoro"</string>
+ <string name="category_work" msgid="4014193632325996115">"Di lavoro"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opzioni sviluppatore"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Attiva Opzioni sviluppatore"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Imposta opzioni per lo sviluppo di applicazioni"</string>
@@ -435,15 +435,11 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fino alle ore <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro le <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il telefono potrebbe spegnersi a breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il tablet potrebbe spegnersi a breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il dispositivo potrebbe spegnersi a breve"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 53f82eba9c39..a7862a15a520 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"אמורה להחזיק מעמד בערך עד <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"עד <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ייתכן שהסוללה תתרוקן עד <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"יש פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"יש פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"יש יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"יש יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"הטלפון עלול להיכבות בקרוב"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"הטאבלט עלול להיכבות בקרוב"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"המכשיר עלול להיכבות בקרוב"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 2f91ea639263..9947b18ec5da 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"電池が切れる推定時刻: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> まで"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> 頃に電池がなくなります"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)未満"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)以上"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>以上"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"スマートフォンの電源がもうすぐ切れます"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"タブレットの電源がもうすぐ切れます"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"デバイスの電源がもうすぐ切れます"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 965a76dad9de..5240b0c54978 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -435,7 +435,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)-მდე"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>-მდე"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>-მდე"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ბატარეა შესაძლოა ამოიწუროს <xliff:g id="TIME">%1$s</xliff:g>-ისთვის"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ბატარეა შესაძლოა ამოიწუროს <xliff:g id="TIME">%1$s</xliff:g>-მდე"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"დარჩა <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"დარჩა <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"დარჩა <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ზე მეტი (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 5aec86bc5705..84d0bb65c25a 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> дейін жетеді"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> дейін"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея заряды сағат <xliff:g id="TIME">%1$s</xliff:g> қарай бітуі мүмкін."</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Ең азы <xliff:g id="THRESHOLD">%1$s</xliff:g> қалды"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Ең азы <xliff:g id="THRESHOLD">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Ең көбі <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Ең көбі <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон көп ұзамай өшуі мүмкін"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет көп ұзамай өшуі мүмкін"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Құрылғы көп ұзамай өшуі мүмкін"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index aa5205264942..f1e42db85619 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"មធ្យម"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"លឿន"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"លឿន​ខ្លាំង"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ផុតកំណត់"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"បានផុតកំណត់"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"បាន​ផ្ដាច់"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"កំពុង​ផ្ដាច់…"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"គួរ​តែ​អាច​ប្រើបាន​រហូតដល់​ម៉ោងប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"រហូតដល់​ម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"អាចនឹង​អស់ថ្ម​ត្រឹមម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"នៅសល់​តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"នៅសល់​តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"នៅសល់​ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"នៅសល់​ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ទូរសព្ទ​អាច​នឹង​បិទ​ក្នុង​ពេល​បន្តិច​ទៀត"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ថេប្លេត​អាចនឹង​បិទក្នុង​ពេលបន្តិច​ទៀត"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ឧបករណ៍​អាចនឹង​បិទក្នុង​ពេលបន្តិច​ទៀត"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9dbeb45cea8e..7c20c94b0ea3 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"대략 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>까지"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"예상 배터리 종료 시간: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"휴대전화가 곧 종료될 수 있음"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"태블릿이 곧 종료될 수 있음"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"기기가 곧 종료될 수 있음"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 66c5c4fb09f5..8ec5f3ac661c 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Орто"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Ылдам"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Абдан ылдам"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мөөнөтү бүткөн"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Эскирип калган"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылган"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылууда…"</string>
@@ -76,7 +76,7 @@
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Туташып турат (телефониясыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Туташып турат (медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Туташып турат (телефониясыз же медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Жигердүү, батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Иштеп жатат, батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Активдүү, сол: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, оң: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Сол: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, оң: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Болжол менен саат <xliff:g id="TIME">%1$s</xliff:g> өчөт"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> чейин"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея <xliff:g id="TIME">%1$s</xliff:g> отуруп калышы мүмкүн"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> азыраак калды"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> азыраак калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> көбүрөөк калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> көбүрөөк калды"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон бир аздан кийин өчүп калышы мүмкүн"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет бир аздан кийин өчүп калышы мүмкүн"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Түзмөк бир аздан кийин өчүп калышы мүмкүн"</string>
@@ -458,7 +454,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Жай кубатталууда"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Кубат алган жок"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Сайылып турат, учурда кубаттоо мүмкүн эмес"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"сайылып турат, бирок кубатталган жок"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"Толук"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Администратор тарабынан көзөмөлдөнөт"</string>
<string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 4772124307f6..cc43d5aeff9b 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Turėtų išsikrauti maždaug po <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Iki <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akumuliatoriaus energija gali išsekti <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonas netrukus gali būti išjungtas"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planšetinis komp. netrukus gali būti išjungtas"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Įrenginys netrukus gali būti išjungtas"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 33806451220b..249489ed6140 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> хүртэл барих ёстой"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> хүртэл"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарейн цэнэг <xliff:g id="TIME">%1$s</xliff:g> гээд дуусаж болзошгүй"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага үлдсэн"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их үлдсэн"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Утас удахгүй унтарч болзошгүй"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет удахгүй унтарч болзошгүй"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Төхөөрөмж удахгүй унтарч болзошгүй"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index f34e2b81498d..fa36975559b6 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Seharusnya boleh digunakan hingga kira-kira <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateri mungkin habis menjelang <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon mungkin ditutup tidak lama lagi"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet mungkin ditutup tidak lama lagi"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Peranti mungkin ditutup tidak lama lagi"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 3f3877110f14..e374d65f21a7 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan gå tomt <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen slås kanskje av snart"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Nettbrettet slås kanskje av snart"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten slås kanskje av snart"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 9a839fa0f32a..d6856a762825 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -251,8 +251,7 @@
<string name="wifi_display_certification" msgid="1805579519992520381">"ताररहित प्रदर्शन प्रमाणीकरण"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi स्क्यान थ्रोटलिङ"</string>
- <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) -->
- <skip />
+ <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi द्वारा परिष्कृत MAC ठेगाना बदल्ने सुविधा"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string>
@@ -285,8 +284,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ब्याट्रीको खपत कम गरी नेटवर्कको कार्यसम्पादनमा सुधार गर्दछ"</string>
- <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) -->
- <skip />
+ <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"यो टगलले क्लाइन्ट मोडमा मात्र MAC ठेगाना बदल्ने सुविधामा असर पार्न सक्छ।\nयो मोड सक्रिय हुँदा MAC बदल्ने सुविधा सक्षम पारेको कुनै पनि नेटवर्कको MAC ठेगाना पुनः बदल्न सकिन्छ। यसका लागि नेटवर्क कनेक्ट भएको हुनु पर्छ। यो कुरा क्लाइन्टले उक्त नेटवर्क पछिल्लो पटक कहिले डिस्कनेक्ट गरेको थियो भन्ने कुरामा पनि भर पर्छ। यन्त्र ४ घन्टा वा सोभन्दा कम समयमा फेरि कनेक्ट हुन्छ भने MAC ठेगाना पुनः बदलिँदैन।"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"सशुल्क वाइफाइ"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"मिटर नगरिएको"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"लगर बफर आकारहरू"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 176a8b7ca5cf..d034b496384d 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batterij is waarschijnlijk leeg om <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Nog minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Nog meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefoon wordt binnenkort mogelijk uitgeschakeld"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet wordt binnenkort mogelijk uitgeschakeld"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Apparaat wordt binnenkort mogelijk uitgeschakeld"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index e1610fb9406f..cedf0bfef509 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -154,9 +154,9 @@
<string name="running_process_item_user_label" msgid="3988506293099805796">"ଉପଯୋଗକର୍ତ୍ତା: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"କିଛି ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ମାନ ସେଟ୍‌ ହୋଇଛି"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"କୌଣସି ପୂର୍ବ-ନିର୍ଦ୍ଧାରଣ ସେଟ୍‍ ହୋଇନାହିଁ"</string>
- <string name="tts_settings" msgid="8130616705989351312">"ଲେଖା-ରୁ-କଥା ସେଟିଙ୍ଗ୍‌"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"ଲେଖା-ରୁ-କଥା ଆଉଟପୁଟ୍‌"</string>
- <string name="tts_default_rate_title" msgid="3964187817364304022">"ସ୍ପୀଚ୍‌ ବେଗ"</string>
+ <string name="tts_settings" msgid="8130616705989351312">"ଟେକ୍ସଟ-ରୁ-ସ୍ପିଚ୍ ସେଟିଂସ୍"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"ଟେକ୍ସଟ-ରୁ-ସ୍ପିଚ୍ ଆଉଟପୁଟ୍‌"</string>
+ <string name="tts_default_rate_title" msgid="3964187817364304022">"ସ୍ପିଚ୍‌ ରେଟ୍"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"ଲେଖା ପଢ଼ିବାର ବେଗ"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"ପିଚ୍‌"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"ସଂଶ୍ଳେଷିତ ସ୍ପିଚ୍‌‌ର ଟୋନ୍‌ରେ ପ୍ରଭାବ ପକାଏ"</string>
@@ -421,7 +421,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ପ୍ରୋଟାନୋମାଲି (ଲାଲ୍‌-ସବୁଜ)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ନୀଳ-ହଳଦିଆ)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"ଆପଣଙ୍କ ଡିଭାଇସରେ ରଙ୍ଗଗୁଡ଼ିକ କିପରି ଡିସପ୍ଲେ ହୁଏ ତାହା ଆଡଜଷ୍ଟ କରିବାକୁ ’କଲର୍ କରେକ୍ସନ୍’ ଆପଣଙ୍କୁ ଅନୁମତି ଦିଏ"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"ଆପଣଙ୍କ ଡିଭାଇସରେ ରଙ୍ଗଗୁଡ଼ିକ କିପରି ଡିସପ୍ଲେ ହୁଏ, ତାହା ଆଡଜଷ୍ଟ କରିବାକୁ \'ରଙ୍ଗ ସଂଶୋଧନ’ ଆପଣଙ୍କୁ ଅନୁମତି ଦିଏ"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍‌ରାଇଡ୍‌ କରାଯାଇଛି"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string>
@@ -536,16 +536,16 @@
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"ନିଜ ଆକାଉଣ୍ଟରୁ ଆପ୍‌ ତଥା କଣ୍ଟେଣ୍ଟକୁ ଆପଣ ଆକ୍ସେସ୍ ରୋକିପାରିବେ"</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"ଉପଯୋଗକର୍ତ୍ତା"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"ସୀମିତ ସୁବିଧା ଥିବା ପ୍ରୋଫାଇଲ୍‌"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"ନୂତନ ୟୁଜର୍ ଯୋଡ଼ିବେ?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ୟୁଜର୍ ତିଆରିକରି ଆପଣ ଏହି ଡିଭାଇସ୍‌କୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର୍ କରିପାରିବେ। ପ୍ରତ୍ୟେକ ୟୁଜର୍‌ଙ୍କର ନିଜର ସ୍ପେସ୍ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ୍, ୱାଲପେପର୍ ଓ ଏପରି ଅନେକ ସହିତ କଷ୍ଟମାଇଜ୍ କରିପାରିବେ। ୟୁଜର୍ ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ୍ ସେଟିଙ୍ଗକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଗୋଟିଏ ନୂଆ ୟୁଜର୍‌ଙ୍କୁ ଯୋଡ଼ିବେ ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତି ଜଣଙ୍କୁ ନିଜର ସ୍ପେସ୍‌କୁ ସେଟ‌ଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ୟୁଜରଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍ ଆପ୍‌କୁ ଅପଡେଟ୍ କରିପାରିବେ। ଆକ୍ସେସ୍ କରିବା ପାଇଁ ସେଟିଙ୍ଗ ଏବଂ ସେବା ନୂଆ ୟୁଜର୍‌ଙ୍କୁ ଟ୍ରନ୍ସଫର୍ ନହୋ‌ଇପାରେ।"</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ?"</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରି ଆପଣ ଏହି ଡିଭାଇସ୍‌କୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର୍ କରିପାରିବେ। ପ୍ରତ୍ୟେକ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନିଜର ସ୍ପେସ୍ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ୍, ୱାଲପେପର୍ ଓ ଏପରି ଅନେକ କିଛି ସହିତ କଷ୍ଟମାଇଜ୍ କରିପାରିବେ। ଉପଯୋଗକର୍ତ୍ତା ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ୍ ସେଟିଂସକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଗୋଟିଏ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ, ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ନିଜର ସ୍ପେସ୍‌କୁ ସେଟ‌ଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପ୍‌କୁ ଅପଡେଟ୍ କରିପାରିବେ। ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ୍ ଏବଂ ସେବା ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ସ୍ଥାନାନ୍ତର ହୋ‌ଇନପାରେ।"</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍‍ କରିବାକୁ ପଡ଼ିବ।\n\nଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେକୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପ୍‌ଗୁଡ଼ିକୁ ଅପ୍‌ଡେଟ୍‌ କରିପାରିବେ।"</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ୟୁଜର୍‌ଙ୍କୁ ସେଟ୍ କରିବେ?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍‌ ଓ ନିଜର ସ୍ଥାନ ସେଟ୍‌ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ଉପଯୋଗକର୍ତ୍ତା ସେଟଅପ କରିବେ?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍‌ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ୍‌ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ପ୍ରୋଫାଇଲ୍‌କୁ ଏବେ ସେଟ୍‌ କରିବେ?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟଅପ୍ କରନ୍ତୁ"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"ଏବେ ନୁହେଁଁ"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"ଯୋଡନ୍ତୁ"</string>
- <string name="user_new_user_name" msgid="60979820612818840">"ନୂଆ ୟୁଜର୍"</string>
+ <string name="user_new_user_name" msgid="60979820612818840">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
<string name="user_new_profile_name" msgid="2405500423304678841">"ନୂଆ ପ୍ରୋଫାଇଲ୍‌"</string>
<string name="user_info_settings_title" msgid="6351390762733279907">"ଉପଯୋଗକର୍ତ୍ତା ସୂଚନା"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"ପ୍ରୋଫାଇଲ୍ ସୂଚନା"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d371c5254708..cc0543e01966 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Osobiste"</string>
- <string name="category_work" msgid="4014193632325996115">"Praca"</string>
+ <string name="category_work" msgid="4014193632325996115">"Służbowe"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opcje programistyczne"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje dla programistów"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Powinno wystarczyć do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria może się wyczerpać do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Wkrótce telefon może się wyłączyć"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet może się wkrótce wyłączyć"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Urządzenie może się wkrótce wyłączyć"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index e3adb389484c..6318c6d460b7 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -61,7 +61,7 @@
<string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desligado"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"A desligar..."</string>
@@ -508,7 +508,7 @@
<string name="alarm_template_far" msgid="6382760514842998629">"no(a) <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"Até ser desativado"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"Até desativar"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altifalante do telemóvel"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index fa43c13c7ccb..f64cfbfe07b5 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Ar trebui să reziste până la <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Până la <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria se poate descărca până la <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonul se poate închide în curând"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tableta se poate închide în curând"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Dispozitivul se poate închide în curând"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index bb060711cf17..71c7cf352f7c 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Заряда хватит примерно до <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея может разрядиться к <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Осталось менее <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит менее чем на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит более чем на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Осталось более <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон скоро выключится"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет скоро выключится"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Устройство скоро выключится"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index ea8cf7313d91..f988d468fede 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -435,15 +435,11 @@
<string name="power_discharge_by" msgid="4113180890060388350">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batéria sa môže do <xliff:g id="TIME">%1$s</xliff:g> minúť"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batéria sa môže do <xliff:g id="TIME">%1$s</xliff:g> vybiť"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefón sa môže čoskoro vypnúť"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sa môže čoskoro vypnúť"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zariadenie sa môže čoskoro vypnúť"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 893b20739717..eb2077cfbf44 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Moralo bi zadostovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Energije baterije lahko zmanjka do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostaja manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostaja manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostaja več kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostaja več kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se bo morda kmalu zaustavil"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablični računalnik se bo morda kmalu zaustavil"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Naprava se bo morda kmalu zaustavila"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 72b28ce5ece6..685be99fdab0 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -454,7 +454,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Po karikohet ngadalë"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Në prizë, por nuk mund të ngarkohet për momentin"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Në prizë, por nuk mund të karikohet për momentin"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"E mbushur"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolluar nga administratori"</string>
<string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e47969cef612..9188a76248ac 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерија ће се можда испразнити до <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон ће се ускоро искључити"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет ће се ускоро искључити"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уређај ће се ускоро искључити"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index c21e62490f0a..c383e57739bb 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Bör räcka ungefär till klockan <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Till kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan ta slut klockan <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen kanske stängs av snart"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Surfplattan kanske stängs av snart"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten kanske stängs av snart"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 844a329b8df5..315fab9c0052 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"น่าจะใช้งานได้ถึงเวลาประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"จนถึง <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"แบตเตอรี่อาจหมดภายใน <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"เหลือน้อยกว่า <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"เหลือน้อยกว่า <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"เหลืออีกกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"เหลืออีกกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"โทรศัพท์อาจปิดเครื่องในไม่ช้า"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"อุปกรณ์อาจปิดเครื่องในไม่ช้า"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 412be0f2b3aa..2ea03a4eaa71 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Posibleng maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baka mag-shut down na ang telepono"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baka mag-shut down na ang tablet"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baka mag-shut down na ang device"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 6f6b3fc84cf1..a6021d233555 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Вистачить приблизно до <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятор може розрядитися до <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон може невдовзі вимкнутися"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет може невдовзі вимкнутися"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Пристрій може невдовзі вимкнутися"</string>
@@ -458,7 +454,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Повільне заряджання"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряджається"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Підключено. Не вдається зарядити"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Підключено, не заряджається"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"Акумулятор заряджено"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Керується адміністратором"</string>
<string name="disabled" msgid="8017887509554714950">"Вимкнено"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 215cb4c83d58..3089b7091eea 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -76,7 +76,7 @@
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefondan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefon yoki mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Faol, batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Faol, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Faol, L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
@@ -129,8 +129,8 @@
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
<string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Chap eshitish apparati ulanmoqda…"</string>
<string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"O‘ng eshitish apparati ulanmoqda…"</string>
- <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Chap eshitish apparati – batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"O‘ng eshitish apparati – batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Chap eshitish apparati, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"O‘ng eshitish apparati, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="accessibility_wifi_off" msgid="1195445715254137155">"Wi-Fi o‘chiq."</string>
<string name="accessibility_no_wifi" msgid="5297119459491085771">"Wi-Fi o‘chiq."</string>
<string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wi-Fi: bitta ustun"</string>
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> gacha"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya quvvati tugash vaqti: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kam qoldi"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kam qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan koʻproq qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan koʻproq qoldi"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tez orada oʻchib qolishi mumkin"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planshet tez orada oʻchib qolishi mumkin"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Qurilma tez orada oʻchib qolishi mumkin"</string>
@@ -451,8 +447,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Planshet tez orada oʻchib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Qurilma tez orada oʻchib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻliq quvvat oladi"</string>
- <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻliq quvvat oladi"</string>
+ <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻladi"</string>
+ <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻladi"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index e118ec0b72f1..32fbcc90963f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Pin sẽ hết vào khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Cho đến <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Điện thoại có thể hết pin vào <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Còn chưa đến <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Còn chưa đến <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Còn hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Còn hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Điện thoại có thể sắp tắt"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Máy tính bảng có thể sắp tắt"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Thiết bị có thể sắp tắt"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 9edcff2c6e5e..7270c2e2971d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"直到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"剩余电池续航时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"剩余电池续航时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手机可能即将关机"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板电脑可能即将关机"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"设备可能即将关机"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 974831f19cfe..5d73f3e5ee13 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -435,7 +435,7 @@
<string name="power_discharge_by" msgid="4113180890060388350">"電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"電量大約可用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"還可用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g>耗盡"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g> 耗盡"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩餘電量少於 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩餘電量少於 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"剩餘電量時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 04b5cb6ba2c9..43caf5ae6cce 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"預估電力大約可使用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電力可能於<xliff:g id="TIME">%1$s</xliff:g> 前耗盡"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手機可能即將關機"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板電腦可能即將關機"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"裝置可能即將關機"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 7e849189f62e..6cb24e6e55d2 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -436,14 +436,10 @@
<string name="power_discharge_by_only" msgid="92545648425937000">"Kumele ihlale cishe kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuze kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Ibhethri lingaphela ngo-<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) -->
- <skip />
- <!-- no translation found for power_remaining_less_than_duration (318215464914990578) -->
- <skip />
- <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) -->
- <skip />
- <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) -->
- <skip />
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kusele okungaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kusele okungaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Kusele okungaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Kusele okungaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Ifoni ingacisha maduze"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Ithebulethi ingacisha maduze"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Idivayisi ingacisha maduze"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index f4857932064f..eb02a1c8b880 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -279,8 +279,12 @@ public class Utils {
}
public static int getThemeAttr(Context context, int attr) {
+ return getThemeAttr(context, attr, 0);
+ }
+
+ public static int getThemeAttr(Context context, int attr, int defaultValue) {
TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
- int theme = ta.getResourceId(0, 0);
+ int theme = ta.getResourceId(0, defaultValue);
ta.recycle();
return theme;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
index ee8fb38ef08c..74a59399feee 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -89,6 +89,13 @@ public class BluetoothMediaDevice extends MediaDevice {
}
@Override
+ public boolean isFastPairDevice() {
+ return mCachedDevice != null
+ && BluetoothUtils.getBooleanMetaData(
+ mCachedDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET);
+ }
+
+ @Override
public boolean isConnected() {
return mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
&& mCachedDevice.isConnected();
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 19c8b20b7822..002bbec60924 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -17,11 +17,16 @@ package com.android.settingslib.media;
import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_HDMI;
import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
+import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
+import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
+import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
@@ -339,7 +344,7 @@ public class InfoMediaManager extends MediaManager {
for (MediaRoute2Info route : mRouterManager.getAllRoutes()) {
if (DEBUG) {
Log.d(TAG, "buildAllRoutes() route : " + route.getName() + ", volume : "
- + route.getVolume());
+ + route.getVolume() + ", type : " + route.getType());
}
if (route.isSystemRoute()) {
addMediaDevice(route);
@@ -350,13 +355,15 @@ public class InfoMediaManager extends MediaManager {
private void buildAvailableRoutes() {
for (MediaRoute2Info route : mRouterManager.getAvailableRoutes(mPackageName)) {
if (DEBUG) {
- Log.d(TAG, "buildAvailableRoutes() route : " + route.getName());
+ Log.d(TAG, "buildAvailableRoutes() route : " + route.getName()
+ + ", type : " + route.getType());
}
addMediaDevice(route);
}
}
- private void addMediaDevice(MediaRoute2Info route) {
+ @VisibleForTesting
+ void addMediaDevice(MediaRoute2Info route) {
final int deviceType = route.getType();
MediaDevice mediaDevice = null;
switch (deviceType) {
@@ -374,6 +381,11 @@ public class InfoMediaManager extends MediaManager {
}
break;
case TYPE_BUILTIN_SPEAKER:
+ case TYPE_USB_DEVICE:
+ case TYPE_USB_HEADSET:
+ case TYPE_USB_ACCESSORY:
+ case TYPE_DOCK:
+ case TYPE_HDMI:
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
mediaDevice =
@@ -385,8 +397,10 @@ public class InfoMediaManager extends MediaManager {
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(route.getOriginalId());
final CachedBluetoothDevice cachedDevice =
mBluetoothManager.getCachedDeviceManager().findDevice(device);
- mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice, mRouterManager,
- route, mPackageName);
+ if (cachedDevice != null) {
+ mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice, mRouterManager,
+ route, mPackageName);
+ }
break;
default:
Log.w(TAG, "addMediaDevice() unknown device type : " + deviceType);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index a62d76f732da..af691783e85d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -35,6 +35,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -185,7 +186,7 @@ public class LocalMediaManager implements BluetoothCallback {
}
void dispatchDeviceListUpdate() {
- //TODO(b/149260820): Use new rule to rank device once device type api is ready.
+ Collections.sort(mMediaDevices, COMPARATOR);
for (DeviceCallback callback : getCallbacks()) {
callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices));
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 6aff301f57d4..f1c0f6b44150 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -17,11 +17,16 @@ package com.android.settingslib.media;
import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_HDMI;
import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
+import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
+import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
+import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
@@ -102,6 +107,13 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
case TYPE_WIRED_HEADPHONES:
mType = MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE;
break;
+ case TYPE_USB_DEVICE:
+ case TYPE_USB_HEADSET:
+ case TYPE_USB_ACCESSORY:
+ case TYPE_DOCK:
+ case TYPE_HDMI:
+ mType = MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE;
+ break;
case TYPE_HEARING_AID:
case TYPE_BLUETOOTH_A2DP:
mType = MediaDeviceType.TYPE_BLUETOOTH_DEVICE;
@@ -266,16 +278,22 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
/**
* Rules:
- * 1. If there is one of the connected devices identified as a carkit, this carkit will
- * be always on the top of the device list. Rule 2 and Rule 3 can’t overrule this rule.
+ * 1. If there is one of the connected devices identified as a carkit or fast pair device,
+ * the fast pair device will be always on the first of the device list and carkit will be
+ * second. Rule 2 and Rule 3 can’t overrule this rule.
* 2. For devices without any usage data yet
* WiFi device group sorted by alphabetical order + BT device group sorted by alphabetical
* order + phone speaker
* 3. For devices with usage record.
* The most recent used one + device group with usage info sorted by how many times the
* device has been used.
- * 4. Phone device always in the top and the connected Bluetooth devices, cast devices and
- * phone device will be always above on the disconnect Bluetooth devices.
+ * 4. The order is followed below rule:
+ * 1. USB-C audio device
+ * 2. 3.5 mm audio device
+ * 3. Bluetooth device
+ * 4. Cast device
+ * 5. Cast group device
+ * 6. Phone
*
* So the device list will look like 5 slots ranked as below.
* Rule 4 + Rule 1 + the most recently used device + Rule 3 + Rule 2
@@ -295,39 +313,50 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
}
}
- // Phone device always in the top.
- if (mType == MediaDeviceType.TYPE_PHONE_DEVICE) {
- return -1;
- } else if (another.mType == MediaDeviceType.TYPE_PHONE_DEVICE) {
- return 1;
- }
- // Check carkit
- if (isCarKitDevice()) {
- return -1;
- } else if (another.isCarKitDevice()) {
- return 1;
- }
- // Set last used device at the first item
- String lastSelectedDevice = ConnectionRecordManager.getInstance().getLastSelectedDevice();
- if (TextUtils.equals(lastSelectedDevice, getId())) {
- return -1;
- } else if (TextUtils.equals(lastSelectedDevice, another.getId())) {
- return 1;
- }
- // Sort by how many times the device has been used if there is usage record
- if ((mConnectedRecord != another.mConnectedRecord)
- && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) {
- return (another.mConnectedRecord - mConnectedRecord);
- }
- // Both devices have never been used
- // To devices with the same type, sort by alphabetical order
if (mType == another.mType) {
+ // Check fast pair device
+ if (isFastPairDevice()) {
+ return -1;
+ } else if (another.isFastPairDevice()) {
+ return 1;
+ }
+
+ // Check carkit
+ if (isCarKitDevice()) {
+ return -1;
+ } else if (another.isCarKitDevice()) {
+ return 1;
+ }
+
+ // Set last used device at the first item
+ final String lastSelectedDevice = ConnectionRecordManager.getInstance()
+ .getLastSelectedDevice();
+ if (TextUtils.equals(lastSelectedDevice, getId())) {
+ return -1;
+ } else if (TextUtils.equals(lastSelectedDevice, another.getId())) {
+ return 1;
+ }
+ // Sort by how many times the device has been used if there is usage record
+ if ((mConnectedRecord != another.mConnectedRecord)
+ && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) {
+ return (another.mConnectedRecord - mConnectedRecord);
+ }
+
+ // Both devices have never been used
+ // To devices with the same type, sort by alphabetical order
final String s1 = getName();
final String s2 = another.getName();
return s1.compareToIgnoreCase(s2);
+ } else {
+ // Both devices have never been used, the priority is:
+ // 1. USB-C audio device
+ // 2. 3.5 mm audio device
+ // 3. Bluetooth device
+ // 4. Cast device
+ // 5. Cast group device
+ // 6. Phone
+ return mType < another.mType ? -1 : 1;
}
- // Both devices have never been used, the priority is Phone > Cast > Bluetooth
- return mType - another.mType;
}
/**
@@ -338,6 +367,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
return false;
}
+ /**
+ * Check if it is FastPair device
+ * @return {@code true} if it is FastPair device, otherwise return {@code false}
+ */
+ protected boolean isFastPairDevice() {
+ return false;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MediaDevice)) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index c6c5ade90eb5..42f2542e5c30 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -16,6 +16,11 @@
package com.android.settingslib.media;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_DOCK;
+import static android.media.MediaRoute2Info.TYPE_HDMI;
+import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
+import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
+import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
@@ -53,6 +58,13 @@ public class PhoneMediaDevice extends MediaDevice {
switch (mRouteInfo.getType()) {
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
+ name = mContext.getString(R.string.media_transfer_wired_device_name);
+ break;
+ case TYPE_USB_DEVICE:
+ case TYPE_USB_HEADSET:
+ case TYPE_USB_ACCESSORY:
+ case TYPE_DOCK:
+ case TYPE_HDMI:
name = mRouteInfo.getName();
break;
case TYPE_BUILTIN_SPEAKER:
@@ -78,6 +90,11 @@ public class PhoneMediaDevice extends MediaDevice {
int getDrawableResId() {
int resId;
switch (mRouteInfo.getType()) {
+ case TYPE_USB_DEVICE:
+ case TYPE_USB_HEADSET:
+ case TYPE_USB_ACCESSORY:
+ case TYPE_DOCK:
+ case TYPE_HDMI:
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
index a39bcb7f08f6..8973d116e438 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
@@ -18,6 +18,7 @@ package com.android.settingslib.media;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothDevice;
@@ -69,4 +70,30 @@ public class BluetoothMediaDeviceTest {
assertThat(mBluetoothMediaDevice.isConnected()).isFalse();
}
+
+ @Test
+ public void isFastPairDevice_isUntetheredHeadset_returnTrue() {
+ final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+ when(mDevice.getDevice()).thenReturn(bluetoothDevice);
+
+ final String value = "True";
+ final byte[] bytes = value.getBytes();
+ when(bluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
+ .thenReturn(bytes);
+
+ assertThat(mBluetoothMediaDevice.isFastPairDevice()).isTrue();
+ }
+
+ @Test
+ public void isFastPairDevice_isNotUntetheredHeadset_returnFalse() {
+ final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+ when(mDevice.getDevice()).thenReturn(bluetoothDevice);
+
+ final String value = "asjdaioshfaio";
+ final byte[] bytes = value.getBytes();
+ when(bluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
+ .thenReturn(bytes);
+
+ assertThat(mBluetoothMediaDevice.isFastPairDevice()).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index c21582cdf203..76eea67f9765 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -16,20 +16,29 @@
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
+import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
import static android.media.MediaRoute2ProviderService.REASON_NETWORK_ERROR;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.testutils.shadow.ShadowRouter2Manager;
@@ -601,4 +610,60 @@ public class InfoMediaManagerTest {
assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
verify(mCallback).onConnectedDeviceChanged(null);
}
+
+ @Test
+ public void addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice() {
+ final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+ mock(CachedBluetoothDeviceManager.class);
+ final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+
+ when(route2Info.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
+ mInfoMediaManager.addMediaDevice(route2Info);
+ assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof InfoMediaDevice).isTrue();
+
+ when(route2Info.getType()).thenReturn(TYPE_USB_DEVICE);
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(route2Info);
+ assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
+
+ when(route2Info.getType()).thenReturn(TYPE_WIRED_HEADSET);
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(route2Info);
+ assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
+
+ when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
+ when(route2Info.getOriginalId()).thenReturn("00:00:00:00:00:00");
+ when(mLocalBluetoothManager.getCachedDeviceManager())
+ .thenReturn(cachedBluetoothDeviceManager);
+ when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
+ .thenReturn(cachedDevice);
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(route2Info);
+ assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof BluetoothMediaDevice).isTrue();
+
+ when(route2Info.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(route2Info);
+ assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
+ }
+
+ @Test
+ public void addMediaDevice_cachedBluetoothDeviceIsNull_shouldNotAdded() {
+ final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+ mock(CachedBluetoothDeviceManager.class);
+
+ when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
+ when(route2Info.getOriginalId()).thenReturn("00:00:00:00:00:00");
+ when(mLocalBluetoothManager.getCachedDeviceManager())
+ .thenReturn(cachedBluetoothDeviceManager);
+ when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
+ .thenReturn(null);
+
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(route2Info);
+
+ assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
index 206c8590a952..f3b49a69201b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -16,6 +16,7 @@
package com.android.settingslib.media;
+import static android.bluetooth.BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static com.google.common.truth.Truth.assertThat;
@@ -28,6 +29,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.MediaRoute2Info;
@@ -659,6 +661,7 @@ public class LocalMediaManagerTest {
final BluetoothDevice bluetoothDevice4 = mock(BluetoothDevice.class);
final BluetoothDevice bluetoothDevice5 = mock(BluetoothDevice.class);
final BluetoothDevice bluetoothDevice6 = mock(BluetoothDevice.class);
+ final BluetoothClass bluetoothClass = mock(BluetoothClass.class);
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
final CachedBluetoothDeviceManager cachedManager = mock(CachedBluetoothDeviceManager.class);
bluetoothDevices.add(bluetoothDevice);
@@ -678,6 +681,9 @@ public class LocalMediaManagerTest {
when(cachedManager.findDevice(bluetoothDevice6)).thenReturn(cachedDevice);
when(cachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(cachedDevice.isConnected()).thenReturn(false);
+ when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+ when(bluetoothDevice.getBluetoothClass()).thenReturn(bluetoothClass);
+ when(bluetoothClass.getDeviceClass()).thenReturn(AUDIO_VIDEO_HEADPHONES);
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
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 db05b768f5db..6664870a6257 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
@@ -18,9 +18,11 @@ package com.android.settingslib.media;
import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -210,14 +212,14 @@ public class MediaDeviceTest {
}
@Test
- public void compareTo_carKit_phone_phoneFirst() {
+ public void compareTo_carKit_phone_carKitFirst() {
when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
- mMediaDevices.add(mBluetoothMediaDevice1);
mMediaDevices.add(mPhoneMediaDevice);
+ mMediaDevices.add(mBluetoothMediaDevice1);
- assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
- Collections.sort(mMediaDevices, COMPARATOR);
assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+ Collections.sort(mMediaDevices, COMPARATOR);
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
}
@Test
@@ -281,7 +283,7 @@ public class MediaDeviceTest {
}
@Test
- public void compareTo_info_bluetooth_infoFirst() {
+ public void compareTo_info_bluetooth_bluetoothFirst() {
mMediaDevices.add(mInfoMediaDevice1);
mMediaDevices.add(mBluetoothMediaDevice1);
@@ -291,13 +293,45 @@ public class MediaDeviceTest {
}
@Test
- public void compareTo_bluetooth_phone_phoneFirst() {
- mMediaDevices.add(mBluetoothMediaDevice1);
+ public void compareTo_bluetooth_phone_bluetoothFirst() {
mMediaDevices.add(mPhoneMediaDevice);
+ mMediaDevices.add(mBluetoothMediaDevice1);
+
+ assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+ Collections.sort(mMediaDevices, COMPARATOR);
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+ }
+
+ @Test
+ public void compareTo_bluetooth_wiredHeadset_wiredHeadsetFirst() {
+ final MediaRoute2Info phoneRouteInfo = mock(MediaRoute2Info.class);
+ when(phoneRouteInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+
+ final PhoneMediaDevice phoneMediaDevice = new PhoneMediaDevice(mContext,
+ mMediaRouter2Manager, phoneRouteInfo, TEST_PACKAGE_NAME);
+
+ mMediaDevices.add(mBluetoothMediaDevice1);
+ mMediaDevices.add(phoneMediaDevice);
assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
Collections.sort(mMediaDevices, COMPARATOR);
- assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+ assertThat(mMediaDevices.get(0)).isEqualTo(phoneMediaDevice);
+ }
+
+ @Test
+ public void compareTo_info_wiredHeadset_wiredHeadsetFirst() {
+ final MediaRoute2Info phoneRouteInfo = mock(MediaRoute2Info.class);
+ when(phoneRouteInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+
+ final PhoneMediaDevice phoneMediaDevice = new PhoneMediaDevice(mContext,
+ mMediaRouter2Manager, phoneRouteInfo, TEST_PACKAGE_NAME);
+
+ mMediaDevices.add(mInfoMediaDevice1);
+ mMediaDevices.add(phoneMediaDevice);
+
+ assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice1);
+ Collections.sort(mMediaDevices, COMPARATOR);
+ assertThat(mMediaDevices.get(0)).isEqualTo(phoneMediaDevice);
}
@Test
@@ -338,7 +372,7 @@ public class MediaDeviceTest {
// 5.mBluetoothMediaDevice2: * 2 times usage
// 6.mBluetoothMediaDevice3: * 1 time usage
// 7.mPhoneMediaDevice: * 0 time usage
- // Order: 7 -> 2 -> 1 -> 5 -> 3 -> 6 -> 4
+ // Order: 2 -> 5 -> 6 -> 1 -> 3 -> 4 -> 7
@Test
public void compareTo_mixedDevices_carKitFirst() {
when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
@@ -360,13 +394,13 @@ public class MediaDeviceTest {
mInfoMediaDevice1.connect();
Collections.sort(mMediaDevices, COMPARATOR);
- assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
- assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice1);
- assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice1);
- assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice2);
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+ assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice2);
+ assertThat(mMediaDevices.get(2)).isEqualTo(mBluetoothMediaDevice3);
+ assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice1);
assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice2);
- assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice3);
- assertThat(mMediaDevices.get(6)).isEqualTo(mInfoMediaDevice3);
+ assertThat(mMediaDevices.get(5)).isEqualTo(mInfoMediaDevice3);
+ assertThat(mMediaDevices.get(6)).isEqualTo(mPhoneMediaDevice);
}
// 1.mInfoMediaDevice1: Last Selected device
@@ -376,7 +410,7 @@ public class MediaDeviceTest {
// 5.mBluetoothMediaDevice2: * 4 times usage not connected
// 6.mBluetoothMediaDevice3: * 1 time usage
// 7.mPhoneMediaDevice: * 0 time usage
- // Order: 7 -> 1 -> 3 -> 6 -> 4 -> 2 -> 5
+ // Order: 6 -> 1 -> 3 -> 4 -> 7 -> 2 -> 5
@Test
public void compareTo_mixedDevices_connectDeviceFirst() {
when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
@@ -402,11 +436,11 @@ public class MediaDeviceTest {
mInfoMediaDevice1.connect();
Collections.sort(mMediaDevices, COMPARATOR);
- assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+ assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice3);
assertThat(mMediaDevices.get(1)).isEqualTo(mInfoMediaDevice1);
assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice2);
- assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice3);
- assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice3);
+ assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice3);
+ assertThat(mMediaDevices.get(4)).isEqualTo(mPhoneMediaDevice);
assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice1);
assertThat(mMediaDevices.get(6)).isEqualTo(mBluetoothMediaDevice2);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
index 4c5cd9682b0f..6f265dd603e5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
@@ -17,6 +17,7 @@
package com.android.settingslib.media;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
@@ -95,9 +96,9 @@ public class PhoneMediaDeviceTest {
when(mInfo.getName()).thenReturn(deviceName);
assertThat(mPhoneMediaDevice.getName())
- .isEqualTo(deviceName);
+ .isEqualTo(mContext.getString(R.string.media_transfer_wired_device_name));
- when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET);
+ when(mInfo.getType()).thenReturn(TYPE_USB_DEVICE);
assertThat(mPhoneMediaDevice.getName())
.isEqualTo(deviceName);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 03f6df0d5d2d..0dd7fb80379d 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -296,6 +296,7 @@ public class SettingsBackupTest {
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
Settings.Global.HDMI_CONTROL_ENABLED,
+ Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HIDDEN_API_POLICY,
diff --git a/packages/SystemUI/res/color/control_foreground.xml b/packages/SystemUI/res/color/control_foreground.xml
index 339f1e20b8b9..de702cdc0263 100644
--- a/packages/SystemUI/res/color/control_foreground.xml
+++ b/packages/SystemUI/res/color/control_foreground.xml
@@ -2,5 +2,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
- <item android:color="@color/GM2_blue_200" />
+ <item android:color="@color/control_enabled_default_foreground" />
</selector>
diff --git a/packages/SystemUI/res/color/thermo_cool_foreground.xml b/packages/SystemUI/res/color/thermo_cool_foreground.xml
index 339f1e20b8b9..ffce33acfcf7 100644
--- a/packages/SystemUI/res/color/thermo_cool_foreground.xml
+++ b/packages/SystemUI/res/color/thermo_cool_foreground.xml
@@ -2,5 +2,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
- <item android:color="@color/GM2_blue_200" />
+ <item android:color="@color/control_enabled_cool_foreground" />
</selector>
diff --git a/packages/SystemUI/res/color/thermo_heat_foreground.xml b/packages/SystemUI/res/color/thermo_heat_foreground.xml
index ffcf55098103..f6ebd0bfdcba 100644
--- a/packages/SystemUI/res/color/thermo_heat_foreground.xml
+++ b/packages/SystemUI/res/color/thermo_heat_foreground.xml
@@ -2,5 +2,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="@color/control_default_foreground" />
- <item android:color="@color/GM2_red_200" />
+ <item android:color="@color/control_enabled_heat_foreground" />
</selector>
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index 66f57fd6f37c..fb57b47f63a0 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -30,6 +30,7 @@
>
<RelativeLayout
android:id="@+id/global_actions_overflow_button"
+ android:contentDescription="@string/accessibility_menu"
android:layout_width="48dp"
android:layout_height="48dp"
>
diff --git a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
new file mode 100644
index 000000000000..e6f27904ee58
--- /dev/null
+++ b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
@@ -0,0 +1,70 @@
+<?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.
+ -->
+
+<com.android.systemui.statusbar.notification.row.HybridConversationNotificationView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical|start"
+ android:paddingEnd="12dp">
+
+ <FrameLayout
+ android:layout_width="@*android:dimen/conversation_content_start"
+ android:layout_height="36dp"
+ >
+ <ImageView
+ android:id="@*android:id/conversation_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="center"
+ />
+
+ <ViewStub
+ android:id="@*android:id/conversation_face_pile"
+ android:layout="@*android:layout/conversation_face_pile_layout"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:layout_gravity="center"
+ />
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/notification_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+
+ android:paddingEnd="8dp"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+ />
+
+ <TextView
+ android:id="@+id/conversation_notification_sender"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ style="?attr/hybridNotificationTextStyle"
+ />
+
+ <TextView
+ android:id="@+id/notification_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ style="?attr/hybridNotificationTextStyle"
+ />
+</com.android.systemui.statusbar.notification.row.HybridConversationNotificationView> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 1008d2bb24fd..48248e1c24d0 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer borrels enige tyd"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Bestuur om borrels vanaf hierdie program af te skakel"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Het dit"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-instellings"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 7e2ec10fd90d..d3dd22b2c8d8 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"በማንኛውም ጊዜ አረፋዎችን ይቆጣጠሩ"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"የዚህ መተግበሪያ አረፋዎችን ለማጥፋት አቀናብርን መታ ያድርጉ"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ገባኝ"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"የ<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ቅንብሮች"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 0ada0dc0f9c8..dd108d0497fc 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1019,15 +1019,14 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"التحكّم في فقاعات المحادثات في أي وقت"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"انقر على \"إدارة\" لإيقاف فقاعات المحادثات من هذا التطبيق."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"حسنًا"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"إعدادات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"تظهر في أعلى قسم المحادثات"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"إظهار صورة الملف الشخصي على شاشة القفل"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"تظهر صورة الملف الشخصي على شاشة القفل"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"تظهر كفقاعة عائمة فوق التطبيقات"</string>
- <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مقاطعة ميزة \"عدم الإزعاج\""</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"لا تتقيّد بميزة \"عدم الإزعاج\""</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"حسنًا"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"نافذة تراكب التكبير"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 99cc25d63834..5e0f65c4b3b4 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"বাৰ্তালাপ শাখাটোৰ শীৰ্ষত দেখুৱাওক"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"লক স্ক্ৰীনত প্ৰ\'ফাইল-চিত্ৰ দেখুৱাওক"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"এপ্‌সমূহৰ ওপৰত ওপঙা বাবল হিচাপে দেখা পোৱা যাব"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"অসুবিধা নিদিব সুবিধাটোত ব্যাঘাত জন্মাওক"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"বুজি পালোঁ"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"বিবৰ্ধন অ’ভাৰলে’ৰ ৱিণ্ড’"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"বিবৰ্ধন ৱিণ্ড’"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"বিবৰ্ধন ৱিণ্ড’ৰ নিয়ন্ত্ৰণসমূহ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index bbb51e140252..708d79b6aed0 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Yumrucuqları istənilən vaxt idarə edin"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu tətbiqdə yumrucuqları deaktiv etmək üçün \"İdarə edin\" seçiminə toxunun"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index cef3cceb9cdc..76e30cadad66 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1004,8 +1004,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolišite oblačiće u bilo kom trenutku"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Važi"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a4aea02f98aa..40c083e98936 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Кіруйце ўсплывальнымі апавяшчэннямі ў любы час"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Каб выключыць усплывальныя апавяшчэнні з гэтай праграмы, націсніце \"Кіраваць\""</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зразумела"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Налады \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 9a505cbb8d92..4393f9524272 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Управление на балончетата по всяко време"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Докоснете „Управление“, за да изключите балончетата от това приложение"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Разбрах"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Настройки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index ca0296415510..452a4aead149 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"কথোপকথনের বিভাগের উপরে দেখান"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"লক স্ক্রিনে প্রোফাইল ছবি দেখান"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"অ্যাপের উপরে একটি ভাসমান বুদবুদ হিসেবে দেখা যাবে"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"বিরক্ত করবে না মোডে ব্যাঘাত ঘটাতে পারে"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"বুঝেছি"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"ওভারলে উইন্ডো বড় করে দেখা"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"উইন্ডো বড় করে দেখা"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"উইন্ডো কন্ট্রোল বড় করে দেখা"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 4692c0bd4400..28dda35c178e 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -101,7 +101,7 @@
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Snimanje ekrana"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Snimanje ekrana i zvuka"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Prikaži dodire na ekranu"</string>
- <string name="screenrecord_stop_text" msgid="6549288689506057686">"Dodirnite za zaustavljanje"</string>
+ <string name="screenrecord_stop_text" msgid="6549288689506057686">"Dodirnite da zaustavite"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Zaustavi"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"Pauza"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
@@ -511,7 +511,7 @@
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historija"</string>
<string name="notification_section_header_gentle" msgid="3044910806569985386">"Nečujna obavještenja"</string>
- <string name="notification_section_header_alerting" msgid="3168140660646863240">"Obavještenja koja privlače pažnju"</string>
+ <string name="notification_section_header_alerting" msgid="3168140660646863240">"Zvučna 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>
@@ -1006,7 +1006,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom momentu"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljaj da isključite oblačiće iz ove aplikacije"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumijem"</string>
- <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 3697151f900a..1d08662b3e0a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -416,13 +416,13 @@
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Llum nocturna"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Al vespre"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Fins a l\'alba"</string>
- <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tema fosc"</string>
<string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Estalvi de bateria"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Al vespre"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fins a l\'alba"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla les bombolles en qualsevol moment"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestiona per desactivar les bombolles d\'aquesta aplicació"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entesos"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuració de l\'aplicació <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ves a Configuració per actualitzar el sistema de navegació"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index f996cb9fe152..f228e802437b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bobler når som helst"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryk på Administrer for at deaktivere bobler fra denne app"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Indstillinger for <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index b3142e9b9616..c1df6d54e2f6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Πατήστε Διαχείριση για να απενεργοποιήσετε τα συννεφάκια από αυτήν την εφαρμογή."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Το κατάλαβα."</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Ρυθμίσεις <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 879fc35811a3..53dda2fe729f 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en todo momento"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Presiona Administrar para desactivar las burbujas de esta app"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 7e3fdc7868da..01fdb37efde9 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en cualquier momento"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index fa6447b20e71..5966e0d7930c 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -416,7 +416,7 @@
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Öövalgus"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Sissel. päikeselooj."</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Kuni päikesetõusuni"</string>
- <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Sisselülitam. kell <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Sisse kell <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tume teema"</string>
<string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Akusäästja"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Juhtige mulle igal ajal"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Haldamine"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selge"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 5860af67e0e1..2b2959e22825 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کنترل ابزارک اعلان در هرزمانی"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"برای خاموش کردن «ابزارک اعلان» از این برنامه، روی «مدیریت» ضربه بزنید"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"متوجه‌ام"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"تنظیمات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم به‌روزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای به‌روزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آماده‌به‌کار"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 04204535dc08..4bab845eaf38 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Muuta kuplien asetuksia milloin tahansa"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Hallinnoi, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selvä"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: asetukset"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index da44d8894251..6917db510491 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -36,7 +36,7 @@
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Activer l\'économiseur de pile?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"À propos du mode Économiseur de pile"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activer"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer la fonction Économiseur de pile"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer l\'économiseur de pile"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Paramètres"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string>
@@ -101,7 +101,7 @@
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Enregistrement de l\'écran"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Enregistrement de l\'écran et de l\'audio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les endroits touchés à l\'écran"</string>
- <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toucher pour arrêter"</string>
+ <string name="screenrecord_stop_text" msgid="6549288689506057686">"Touchez ici pour arrêter"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Arrêter"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"Pause"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 0899e0971af4..8ef8334acdbc 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Contrôler les paramètres des bulles"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez aux paramètres pour mettre à jour la navigation système"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 2e910c77f346..bb5ee8e78593 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlar as burbullas en calquera momento"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Para desactivar as burbullas nesta aplicación, toca Xestionar"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Para actualizar a navegación do sistema, vai a Configuración"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
@@ -1008,7 +1007,7 @@
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar imaxe do perfil na pantalla de bloqueo"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Mostrar como burbulla flotante sobre outras apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper modo Non molestar"</string>
- <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Listo"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"Ampliación da ventá de superposición"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 715c40b93c4a..fb539003ae40 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -345,7 +345,7 @@
<string name="quick_settings_dnd_alarms_label" msgid="1241780970469630835">"ફક્ત એલાર્મ્સ"</string>
<string name="quick_settings_dnd_none_label" msgid="8420869988472836354">"સાવ શાંતિ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"બ્લૂટૂથ"</string>
- <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"બ્લૂટૂથ (<xliff:g id="NUMBER">%d</xliff:g> ઉપકરણો)"</string>
+ <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"બ્લૂટૂથ (<xliff:g id="NUMBER">%d</xliff:g> ડિવાઇસ)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="6375098046500790870">"બ્લૂટૂથ બંધ"</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>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"બબલને કોઈપણ સમયે નિયંત્રિત કરો"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"આ ઍપમાંથી બબલને બંધ કરવા માટે મેનેજ કરો પર ટૅપ કરો"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"સમજાઈ ગયું"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> સેટિંગ"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index af45c6805fb8..19799839e7a9 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1001,8 +1001,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जब चाहें, बबल्स को कंट्रोल करें"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ठीक है"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> की सेटिंग"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b5e6474aa343..521ca575525e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Buborékok vezérlése bármikor"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"A Kezelés gombra koppintva kapcsolhatja ki az alkalmazásból származó buborékokat"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Értem"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> beállításai"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f2ec4b9960ca..93f0001f625c 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -99,7 +99,7 @@
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Սարքի բարձրախոսը և խոսափողը"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Սկսել"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Էկրանի տեսագրում"</string>
- <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Էկրանի տեսագրում և աուդիո ձայնագրում"</string>
+ <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Էկրանի տեսագրում և ձայնագրում"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Ցուցադրել էկրանի հպումները"</string>
<string name="screenrecord_stop_text" msgid="6549288689506057686">"Հպեք՝ դադարեցնելու համար"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Կանգնեցնել"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ամպիկների կարգավորումներ"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Հպեք «Կառավարել» կոճակին՝ այս հավելվածի ամպիկներն անջատելու համար։"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Եղավ"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – կարգավորումներ"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f9126db5f131..ac011a3dfc8f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -192,7 +192,7 @@
<string name="accessibility_data_two_bars" msgid="4576231688545173059">"Data dua batang."</string>
<string name="accessibility_data_three_bars" msgid="3036562180893930325">"Data tiga batang."</string>
<string name="accessibility_data_signal_full" msgid="283507058258113551">"Sinyal data penuh."</string>
- <string name="accessibility_wifi_name" msgid="4863440268606851734">"Tersambung ke <xliff:g id="WIFI">%s</xliff:g>."</string>
+ <string name="accessibility_wifi_name" msgid="4863440268606851734">"Terhubung ke <xliff:g id="WIFI">%s</xliff:g>."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tersambung ke <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Terhubung ke <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_no_wimax" msgid="2014864207473859228">"Tidak ada WiMAX."</string>
@@ -203,7 +203,7 @@
<string name="accessibility_ethernet_disconnected" msgid="2097190491174968655">"Ethernet terputus."</string>
<string name="accessibility_ethernet_connected" msgid="3988347636883115213">"Ethernet tersambung."</string>
<string name="accessibility_no_signal" msgid="1115622734914921920">"Tidak ada sinyal."</string>
- <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak tersambung."</string>
+ <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak terhubung."</string>
<string name="accessibility_zero_bars" msgid="1364823964848784827">"0 baris."</string>
<string name="accessibility_one_bar" msgid="6312250030039240665">"Satu garis."</string>
<string name="accessibility_two_bars" msgid="1335676987274417121">"Dua baris."</string>
@@ -373,7 +373,7 @@
<string name="quick_settings_user_title" msgid="8673045967216204537">"Pengguna"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Pengguna baru"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
- <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Tersambung"</string>
+ <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Terhubung"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Tidak Ada Jaringan"</string>
<string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi Mati"</string>
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi Aktif"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index e8e5b7af7b90..0a5c8faee1cd 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Hægt er að stjórna blöðrum hvenær sem er"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ýttu á „Stjórna“ til að slökkva á blöðrum frá þessu forriti"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ég skil"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Stillingar <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index c4b167bff07a..fab1eab2a9e2 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -91,7 +91,7 @@
<string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Avviare la registrazione?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può catturare dati sensibili visibili sullo schermo o riprodotti sul tuo dispositivo. Sono incluse password, dati di pagamento, foto, messaggi e audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può acquisire dati sensibili visibili sullo schermo o riprodotti sul tuo dispositivo, tra cui password, dati di pagamento, foto, messaggi e audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Registra audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio del dispositivo"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Suoni del dispositivo, come musica, chiamate e suonerie"</string>
@@ -373,7 +373,7 @@
<string name="quick_settings_user_title" msgid="8673045967216204537">"Utente"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nuovo utente"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
- <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connesso"</string>
+ <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connessa"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Nessuna rete"</string>
<string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi disattivato"</string>
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi attivo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 894bb03cacb0..09b53b51f574 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"שליטה בבועות, בכל זמן"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"יש להקיש על \'ניהול\' כדי להשבית את הבועות מהאפליקציה הזו"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"הבנתי"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"הגדרות <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 82f77530f1ab..b8e0ef5227fd 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Қалқыма хабарларды реттеу"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бұл қолданбадан қалқыма хабарларды өшіру үшін \"Басқару\" түймесін түртіңіз."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түсінікті"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлері"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index aa1d77660cc1..ebe3659bd09e 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"គ្រប់គ្រង​​ពពុះ​បានគ្រប់ពេល"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"ចុច \"គ្រប់គ្រង\" ដើម្បីបិទ​ពពុះពីកម្មវិធីនេះ"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"យល់ហើយ"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"ការកំណត់ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើ​បច្ចុប្បន្នភាព​ការរុករកក្នុង​ប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅ​កាន់ការកំណត់។"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូល​ទៅកាន់​ការកំណត់ ដើម្បី​ធ្វើបច្ចុប្បន្នភាព​ការរុករក​ក្នុង​ប្រព័ន្ធ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាក​ដំណើរការ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f8e6b1f54066..38ae28d61cf3 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"언제든지 대화창을 제어하세요"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"이 앱에서 대화창을 사용 중지하려면 관리를 탭하세요."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"확인"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> 설정"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ae6c50adf7bd..0e422d4778b8 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -36,7 +36,7 @@
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Батареяны үнөмдөө режимин күйгүзөсүзбү?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Батареяны үнөмдөгүч режими жөнүндө маалымат"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Күйгүзүү"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"Батареяны үнөмдөгүч режимин күйгүзүү"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"Батареяны үнөмдөгүчтү күйгүзүү"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Жөндөөлөр"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi‑Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Экранды авто буруу"</string>
@@ -90,8 +90,8 @@
<string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
- <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып башталсынбы?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойнотулуп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string>
+ <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып баштайсызбы?"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойноп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Түзмөктүн аудиосу"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Музыка, чалуулар жана рингтондор сыяктуу түзмөгүңүздөгү добуштар"</string>
@@ -101,7 +101,7 @@
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Экран жаздырылууда"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Экран жана аудио жаздырылууда"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Экранды басууларды көрсөтүү"</string>
- <string name="screenrecord_stop_text" msgid="6549288689506057686">"Токтотуш үчүн басыңыз"</string>
+ <string name="screenrecord_stop_text" msgid="6549288689506057686">"Токтотуу үчүн басып коюңуз"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Токтотуу"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"Тындыруу"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Улантуу"</string>
@@ -373,7 +373,7 @@
<string name="quick_settings_user_title" msgid="8673045967216204537">"Колдонуучу"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Жаңы колдонуучу"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
- <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Интернет жок"</string>
+ <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Туташкан жок"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Желе жок"</string>
<string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi өчүк"</string>
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi күйүк"</string>
@@ -498,7 +498,7 @@
<string name="user_remove_user_remove" msgid="8387386066949061256">"Алып салуу"</string>
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Батареяны үнөмдөгүч режими күйүк"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Иштин майнаптуулугун начарлатып, фондук дайын-даректерди чектейт"</string>
- <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүч режимин өчүрүү"</string>
+ <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүчтү өчүрүү"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"Бул функцияны аткарган <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кызматы экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Бул функцияны аткарган кызматка экраныңыздагы бардык маалымат же түзмөктө ойнотулуп жаткан нерсе, сырсөздөр, төлөмдөрдүн чоо-жайы, сүрөттөр, билдирүүлөр жана аудио файлдар жеткиликтүү болот."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түшүндүм"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> жөндөөлөрү"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 7374acd07afc..17be731c06c6 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bet kada valdyti burbulus"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Palieskite „Tvarkyti“, kad išjungtumėte burbulus šioje programoje"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Supratau"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ nustatymai"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2ace26779b95..f402323deac3 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1004,8 +1004,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Pārvaldīt burbuļus jebkurā laikā"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Pieskarieties pogai “Pārvaldīt”, lai izslēgtu burbuļus no šīs lietotnes."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Labi"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 67392bb14d52..03af224a320b 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -91,7 +91,7 @@
<string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Да се започне со снимање?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"При снимањето, системот на Android може да ги сними сите чувствителни податоци што се видливи на вашиот екран или пуштени на уредот. Ова вклучува лозинки, податоци за плаќање, фотографии, пораки и аудио."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"При снимањето, системот Android може да ги сними сите чувствителни податоци што се видливи на вашиот екран или пуштени на уредот. Ова вклучува лозинки, податоци за плаќање, фотографии, пораки и аудио."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај аудио"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Аудио од уредот"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук од вашиот уред, како на пр., музика, повици и мелодии"</string>
@@ -211,7 +211,7 @@
<string name="accessibility_signal_full" msgid="5920148525598637311">"Полн сигнал."</string>
<string name="accessibility_desc_on" msgid="2899626845061427845">"Вклучена."</string>
<string name="accessibility_desc_off" msgid="8055389500285421408">"Исклучено."</string>
- <string name="accessibility_desc_connected" msgid="3082590384032624233">"Поврзана."</string>
+ <string name="accessibility_desc_connected" msgid="3082590384032624233">"Поврзано."</string>
<string name="accessibility_desc_connecting" msgid="8011433412112903614">"Се поврзува."</string>
<string name="data_connection_gprs" msgid="2752584037409568435">"GPRS"</string>
<string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string>
@@ -416,7 +416,7 @@
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ноќно светло"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Вклуч. на зајдисонце"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До изгрејсонце"</string>
- <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Ќе се вклучи во <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Вклучување: <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Темна тема"</string>
<string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Штедач на батерија"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролирајте ги балончињата во секое време"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Допрете „Управувајте“ за да ги исклучите балончињата од апликацијава"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Сфатив"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Поставки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 44a2aa11bbc2..da4dae0c12d6 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്‌റ്റാൻഡ്‌ബൈ"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"സംഭാഷണ വിഭാഗത്തിന്റെ മുകളിൽ കാണിക്കുക"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ലോക്ക് സ്ക്രീനിൽ പ്രൊഫൈൽ ചിത്രം കാണിക്കുക"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ആപ്പുകളുടെ മുകളിൽ ഫ്ലോട്ടിംഗ് ബബിൾ ആയി ദൃശ്യമാകും"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ശല്യപ്പെടുത്തരുത്\' തടസ്സപ്പെടുത്തുക"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"മനസ്സിലായി"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"മാഗ്നിഫിക്കേഷൻ ഓവർലേ വിൻഡോ"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0f17270ac3cc..1e646bc1ac4a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -36,7 +36,7 @@
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Батарей хэмнэгчийг асаах уу?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Батарей хэмнэгчийн тухай"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Асаах"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"Тэжээл хэмнэгчийг асаах"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"Батарей хэмнэгчийг асаах"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Тохиргоо"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Дэлгэцийг автоматаар эргүүлэх"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Дурын үед бөмбөлгийг хянаарай"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Энэ аппын бөмбөлгүүдийг унтраахын тулд Удирдах дээр товшино уу"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ойлголоо"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-н тохиргоо"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 926b636439bc..cd6aa2acdc25 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"संभाषण विभागाच्या सर्वात वरती दाखवा"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लॉक स्‍क्रीनवर प्रोफाइल फोटो दाखवा"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ॲप्सच्या सर्वात वरती फ्लोटिंग बबल म्हणून दिसतील"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"व्यत्यय आणू नका मध्ये अडथळा आणतील"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"समजले"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"मॅग्निफिकेशन ओव्हरले विंडो"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"मॅग्निफिकेशन विंडो नियंत्रणे"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index efd2c851e409..c1c35a1dbfcb 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kawal gelembung pada bila-bila masa"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketik Urus untuk mematikan gelembung daripada apl ini"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Tetapan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 5ee07ae4dfc4..088371e2449e 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollér bobler når som helst"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trykk på Administrer for å slå av bobler for denne appen"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Greit"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-innstillinger"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ec7efdbc2b25..f072dc41af07 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> सञ्चालन गर्न खोल्ने हो?\nयो अनुप्रयोगलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string>
<string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"यस USB उपकरणसँग स्थापित अनुप्रयोग काम गर्दैन। यस उपकरणको बारेमा <xliff:g id="URL">%1$s</xliff:g> मा धेरै जान्नुहोस्"</string>
+ <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"यस USB उपकरणसँग स्थापित एप काम गर्दैन। यस उपकरणको बारेमा <xliff:g id="URL">%1$s</xliff:g> मा धेरै जान्नुहोस्"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"USB सहयोगी"</string>
<string name="label_view" msgid="6815442985276363364">"दृश्य"</string>
<string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> जडान भएको बेला सधैँ <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्नुहोस्"</string>
@@ -85,14 +85,13 @@
<string name="screenshot_failed_title" msgid="3259148215671936891">"स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string>
<string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"भण्डारण ठाउँ सीमित भएका कारण स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
- <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त अनुप्रयोग वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
+ <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त एप वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
<string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रिनसट हटाउनुहोस्"</string>
- <!-- no translation found for screenshot_preview_description (7606510140714080474) -->
- <skip />
+ <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"रेकर्ड गर्न थाल्ने हो?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android प्रणालीले तपाईंको स्क्रिनमा देखिने वा तपाईंको यन्त्रमा प्ले गरिने जुनसुकै संवेदनशील जानकारी समावेश गर्न सक्छ। यसमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android प्रणालीले तपाईंको स्क्रिनमा देखिने वा तपाईंको यन्त्रमा प्ले गरिने सबै संवेदनशील जानकारी रेकर्ड गर्न सक्छ। यो जानकारीमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"यन्त्रको अडियो"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको यन्त्रका सङ्गीत, कल र रिङटोन जस्ता आवाज"</string>
@@ -101,13 +100,13 @@
<string name="screenrecord_start" msgid="330991441575775004">"सुरु गर्नुहोस्"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रिन रेकर्ड गर्दै"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रिन र अडियो रेकर्ड गर्दै"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रिन रेकर्ड गर्ने क्रममा स्पर्श गरिएका स्थानहरू देखाउनुहोस्"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्पर्श गरिएका स्थानहरू देखाउनुहोस्"</string>
<string name="screenrecord_stop_text" msgid="6549288689506057686">"रोक्न ट्याप गर्नुहोस्"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"रोक्नुहोस्"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"पज गर्नुहोस्"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"जारी राख्नुहोस्"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द गर्नुहोस्"</string>
- <string name="screenrecord_share_label" msgid="5025590804030086930">"आदान प्रदान गर्नुहोस्"</string>
+ <string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
<string name="screenrecord_delete_label" msgid="1376347010553987058">"मेट्नुहोस्"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्‌"</string>
@@ -118,7 +117,7 @@
<string name="usb_preference_title" msgid="1439924437558480718">"USB फाइल सार्ने विकल्पहरू"</string>
<string name="use_mtp_button_title" msgid="5036082897886518086">"मिडिया प्लेयर(MTP)को रूपमा माउन्ट गर्नुहोस्"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"क्यामेराको रूपमा माउन्ट गर्नुहोस् (PTP)"</string>
- <string name="installer_cd_button_title" msgid="5499998592841984743">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर अनुप्रयोग स्थापना गर्नुहोस्"</string>
+ <string name="installer_cd_button_title" msgid="5499998592841984743">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर एप स्थापना गर्नुहोस्"</string>
<string name="accessibility_back" msgid="6530104400086152611">"पछाडि"</string>
<string name="accessibility_home" msgid="5430449841237966217">"गृह"</string>
<string name="accessibility_menu" msgid="2701163794470513040">"मेनु"</string>
@@ -356,7 +355,7 @@
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"श्रवण यन्त्रहरू"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सक्रिय गर्दै…"</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"चमक"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"स्वतःघुम्ने"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> मोड"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"परिक्रमण लक गरिएको छ"</string>
@@ -431,8 +430,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"स्रिनको रेकर्ड"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"सुरु गर्नुहोस्"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"रोक्नुहोस्"</string>
- <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"अनुप्रयोगहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string>
- <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"अनुप्रयोगहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string>
+ <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"एपहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"एपहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string>
<string name="expanded_header_battery_charged" msgid="5307907517976548448">"चार्ज भयो"</string>
<string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै"</string>
@@ -475,27 +474,27 @@
<string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string>
- <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै अनुप्रयोगहरू र डेटा मेटाइनेछ।"</string>
+ <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै एपहरू र डेटा मेटाइनेछ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"पुनः स्वागत, अतिथि!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
<string name="guest_notification_title" msgid="4434456703930764167">"अतिथि प्रयोगकर्ता"</string>
- <string name="guest_notification_text" msgid="4202692942089571351">"अनुप्रयोगहरू र डेटा मेटाउन, अतिथि प्रयोगकर्ता हटाउनुहोस्"</string>
+ <string name="guest_notification_text" msgid="4202692942089571351">"एपहरू र डेटा मेटाउन, अतिथि प्रयोगकर्ता हटाउनुहोस्"</string>
<string name="guest_notification_remove_action" msgid="4153019027696868099">"अतिथिलाई हटाउनुहोस्"</string>
<string name="user_logout_notification_title" msgid="3644848998053832589">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
<string name="user_logout_notification_text" msgid="7441286737342997991">"वर्तमान प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
<string name="user_logout_notification_action" msgid="7974458760719361881">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
<string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
+ <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि एपहरू अद्यावधिक गर्न सक्छन्।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
<item quantity="one">एउटा प्रयोगकर्ता मात्र सिर्जना गर्न सकिन्छ।</item>
</plurals>
<string name="user_remove_user_title" msgid="9124124694835811874">"प्रयोगकर्ता हटाउन चाहनुहुन्छ?"</string>
- <string name="user_remove_user_message" msgid="6702834122128031833">"यस प्रयोगकर्ताको सबै अनुप्रयोगहरू तथा डेटा हटाइने छ।"</string>
+ <string name="user_remove_user_message" msgid="6702834122128031833">"यस प्रयोगकर्ताको सबै एपहरू तथा डेटा हटाइने छ।"</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"हटाउनुहोस्"</string>
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ब्याट्री सेभर सक्रिय छ"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"प्रदर्शन र पृष्ठभूमि डेटा घटाउँनुहोस्"</string>
@@ -542,35 +541,35 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN असक्षम गर्नुहोस्"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"विच्छेद VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतिहरू हेर्नुहोस्"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्छ।BREAK\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोगहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"तपाईंको संगठनले तपाईंको यन्त्रको व्यवस्थापन गर्छ।\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोगहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
+ <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्छ।BREAK\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
+ <string name="monitoring_description_management" msgid="8081910434889677718">"तपाईंको संगठनले तपाईंको यन्त्रको व्यवस्थापन गर्छ।\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापित गऱ्यो। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरेको छ। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"यस यन्त्रमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरिएको छ। तपाईंको सुरक्षित नेटवर्कको ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"तपाईंका प्रशासकले तपाईंको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्क लग गर्ने प्रक्रियालाई सक्रिय गर्नुभएको छ।"</string>
- <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तपाईं इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
- <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तपाईं इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP_0">%1$s</xliff:g> र <xliff:g id="VPN_APP_1">%2$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तपाईंको कार्य प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"तपाईंको व्यक्तिगत प्रोफाइल इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string>
+ <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP_0">%1$s</xliff:g> र <xliff:g id="VPN_APP_1">%2$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तपाईंको कार्य प्रोफाइल तपाईंका इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"तपाईंको व्यक्तिगत प्रोफाइल इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"तपाईंको यन्त्र <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> द्वारा व्यवस्थापन गरिएको छ।"</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्न <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> को प्रयोग गर्दछ।"</string>
- <string name="monitoring_description_do_body" msgid="7700878065625769970">"तपाईँको प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोग, तपाईँको यन्त्रसँग सम्बन्धित डेटा र तपाईँको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string>
+ <string name="monitoring_description_do_body" msgid="7700878065625769970">"तपाईँको प्रशासकले सेटिङहरू, संस्थागत पहुँच, एप, तपाईँको यन्त्रसँग सम्बन्धित डेटा र तपाईँको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string>
<string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"थप जान्नुहोस्"</string>
- <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"तपाईं <xliff:g id="VPN_APP">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
+ <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"तपाईं <xliff:g id="VPN_APP">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN सम्बन्धी सेटिङहरू खोल्नुहोस्"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"खुला विश्वसनीय प्रमाणहरू"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"तपाईँको प्रशासकले तपाईँको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्कको लगिङलाई सक्रिय पार्नुभएको छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
- <string name="monitoring_description_vpn" msgid="1685428000684586870">"तपाईँले VPN जडान गर्न अनुप्रयोगलाई अनुमति दिनुभयो।\n\nयो अनुप्रयोगले तपाईँका यन्त्र र नेटवर्क गतिविधि लगायत इमेल, अनुप्रयोग र वेबसाइटहरू अनुगमन गर्न सक्छ।"</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तपाईंको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> ले व्यवस्थापन गर्दछ।\n\nतपाईंको प्रशासकले तपाईंको इमेल, अनुप्रयोग र वेबसाइट सहित नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्नुहुन्छ। \n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।\n\n तपाईं एउटा VPN मा जडित हुनुहुन्छ। यस VPN ले नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्छ।"</string>
+ <string name="monitoring_description_vpn" msgid="1685428000684586870">"तपाईँले VPN जडान गर्न एपलाई अनुमति दिनुभयो।\n\nयो एपले तपाईँका यन्त्र र नेटवर्क गतिविधि लगायत इमेल, एप र वेबसाइटहरू अनुगमन गर्न सक्छ।"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तपाईंको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> ले व्यवस्थापन गर्दछ।\n\nतपाईंको प्रशासकले तपाईंको इमेल, एप र वेबसाइट सहित नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्नुहुन्छ। \n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।\n\n तपाईं एउटा VPN मा जडित हुनुहुन्छ। यस VPN ले नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्छ।"</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="monitoring_description_app" msgid="376868879287922929">"तपाईं आफ्ना इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
- <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, अनुप्रयोगहरू र वेबसाइट लगायतका तपाईंको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string>
- <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायतको तपाईंको व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
- <string name="monitoring_description_app_work" msgid="3713084153786663662">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
- <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string>
+ <string name="monitoring_description_app" msgid="376868879287922929">"तपाईं आफ्ना इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
+ <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, एपहरू र वेबसाइट लगायतका तपाईंको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string>
+ <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, एप र वेबसाइटहरू लगायतको तपाईंको व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
+ <string name="monitoring_description_app_work" msgid="3713084153786663662">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
+ <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string>
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ले खुला राखेको"</string>
<string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"तपाईँले नखोले सम्म उपकरण बन्द रहनेछ"</string>
<string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
@@ -639,7 +638,7 @@
<string name="output_service_bt_wifi" msgid="7186882540475524124">"ब्लुटुथ र Wi-Fi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"प्रणाली UI ट्युनर"</string>
<string name="show_battery_percentage" msgid="6235377891802910455">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string>
- <string name="show_battery_percentage_summary" msgid="9053024758304102915">"चार्ज नगरेको बेला वस्तुस्थिति पट्टी आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string>
+ <string name="show_battery_percentage_summary" msgid="9053024758304102915">"चार्ज नगरेको बेला स्टाटस बार आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string>
<string name="quick_settings" msgid="6211774484997470203">"द्रुत सेटिङहरू"</string>
<string name="status_bar" msgid="4357390266055077437">"स्थिति पट्टी"</string>
<string name="overview" msgid="3522318590458536816">"परिदृश्य"</string>
@@ -666,7 +665,7 @@
<string name="tuner_toast" msgid="3812684836514766951">"बधाईँ छ! सेटिङहरूमा प्रणाली UI ट्युनर थप गरिएको छ"</string>
<string name="remove_from_settings" msgid="633775561782209994">"सेटिङहरूबाट हटाउनुहोस्"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"प्रणाली UI ट्युनर सेटिङहरूबाट हटाउने र यसका सबै सुविधाहरू प्रयोग गर्न रोक्ने हो?"</string>
- <string name="activity_not_found" msgid="8711661533828200293">"तपाईँको यन्त्रमा अनुप्रयोग स्थापना भएको छैन"</string>
+ <string name="activity_not_found" msgid="8711661533828200293">"तपाईँको यन्त्रमा एप स्थापना भएको छैन"</string>
<string name="clock_seconds" msgid="8709189470828542071">"घडीमा सेकेन्ड देखाउनुहोस्"</string>
<string name="clock_seconds_desc" msgid="2415312788902144817">"वस्तुस्थिति पट्टीको घडीमा सेकेन्ड देखाउनुहोस्। ब्याट्री आयु प्रभावित हुन सक्छ।"</string>
<string name="qs_rearrange" msgid="484816665478662911">"द्रुत सेटिङहरू पुनः व्यवस्थित गर्नुहोस्"</string>
@@ -796,7 +795,7 @@
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"सूचनाहरू"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"किबोर्ड सर्टकटहरू"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"किबोर्डको लेआउट बदल्नुहोस्"</string>
- <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"अनुप्रयोगहरू"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"एपहरू"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"सहायता"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउजर"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"सम्पर्कहरू"</string>
@@ -915,7 +914,7 @@
<string name="pip_skip_to_prev" msgid="3742589641443049237">"अघिल्लोमा जानुहोस्"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"तपाईंको फोन अब सामान्य ढंगले चल्दै छ"</string>
- <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने अनुप्रयोगहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन अनुप्रयोगहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने एपहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन एपहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string>
<string name="high_temp_title" msgid="2218333576838496100">"फोन तातो भइरहेको छ"</string>
<string name="high_temp_notif_message" msgid="163928048626045592">"फोन चिसो हुँदै गर्दा केही विशेषताहरूलाई सीमित गरिन्छ"</string>
<string name="high_temp_dialog_message" msgid="3793606072661253968">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string>
@@ -928,24 +927,24 @@
<string name="lockscreen_unlock_right" msgid="4658008735541075346">"दायाँतिरको सर्टकटले पनि अनलक गर्छ"</string>
<string name="lockscreen_none" msgid="4710862479308909198">"कुनै पनि होइन"</string>
<string name="tuner_launch_app" msgid="3906265365971743305">"<xliff:g id="APP">%1$s</xliff:g> सुरु गर्नुहोस्"</string>
- <string name="tuner_other_apps" msgid="7767462881742291204">"अन्य अनुप्रयोगहरू"</string>
+ <string name="tuner_other_apps" msgid="7767462881742291204">"अन्य एपहरू"</string>
<string name="tuner_circle" msgid="5270591778160525693">"सर्कल"</string>
<string name="tuner_plus" msgid="4130366441154416484">"प्लस चिन्ह"</string>
<string name="tuner_minus" msgid="5258518368944598545">"माइनस चिन्ह"</string>
<string name="tuner_left" msgid="5758862558405684490">"बायाँ"</string>
<string name="tuner_right" msgid="8247571132790812149">"दायाँ"</string>
<string name="tuner_menu" msgid="363690665924769420">"मेनु"</string>
- <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> अनुप्रयोग"</string>
+ <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> एप"</string>
<string name="notification_channel_alerts" msgid="3385787053375150046">"सतर्कताहरू"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"ब्याट्री"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"स्क्रिनशटहरू"</string>
<string name="notification_channel_general" msgid="4384774889645929705">"सामान्य सन्देशहरू"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"भण्डारण"</string>
<string name="notification_channel_hints" msgid="7703783206000346876">"सङ्केतहरू"</string>
- <string name="instant_apps" msgid="8337185853050247304">"तात्कालिक अनुप्रयोगहरू"</string>
+ <string name="instant_apps" msgid="8337185853050247304">"तात्कालिक एपहरू"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> चलिरहेको छ"</string>
- <string name="instant_apps_message" msgid="6112428971833011754">"स्थापना नगरिकनै अनुप्रयोग खोलियो।"</string>
- <string name="instant_apps_message_with_help" msgid="1816952263531203932">"स्थापना नगरिकनै अनुप्रयोग खोलियो। थप जान्न ट्याप गर्नुहोस्।"</string>
+ <string name="instant_apps_message" msgid="6112428971833011754">"स्थापना नगरिकनै एप खोलियो।"</string>
+ <string name="instant_apps_message_with_help" msgid="1816952263531203932">"स्थापना नगरिकनै एप खोलियो। थप जान्न ट्याप गर्नुहोस्।"</string>
<string name="app_info" msgid="5153758994129963243">"एपसम्बन्धी जानकारी"</string>
<string name="go_to_web" msgid="636673528981366511">"ब्राउजरमा जानुहोस्"</string>
<string name="mobile_data" msgid="4564407557775397216">"मोबाइल डेटा"</string>
@@ -960,7 +959,7 @@
<string name="qs_dnd_until" msgid="7844269319043747955">"<xliff:g id="ID_1">%s</xliff:g> सम्म"</string>
<string name="qs_dnd_keep" msgid="3829697305432866434">"राख्नुहोस्"</string>
<string name="qs_dnd_replace" msgid="7712119051407052689">"प्रतिस्थापन गर्नुहोस्"</string>
- <string name="running_foreground_services_title" msgid="5137313173431186685">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</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>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"तपाईं <xliff:g id="CARRIER">%s</xliff:g> मार्फत डेटा वा इन्टरनेट प्रयोग गर्न सक्नुहुने छैन। Wi-Fi मार्फत मात्र इन्टरनेट उपलब्ध हुने छ।"</string>
@@ -983,7 +982,7 @@
<string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सरहरू निष्क्रिय छन्"</string>
<string name="device_services" msgid="1549944177856658705">"यन्त्रका सेवाहरू"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string>
- <string name="restart_button_description" msgid="6916116576177456480">"यो अनुप्रयोग पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
+ <string name="restart_button_description" msgid="6916116576177456480">"यो एप पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
<string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> का बबलसम्बन्धी सेटिङहरू"</string>
<string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापन गर्नुहोस्"</string>
<string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> को <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1005,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखाइयोस्"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाइयोस्"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"बुझेँ"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"म्याग्निफिकेसन ओभरले विन्डो"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string>
@@ -1022,7 +1016,7 @@
<string name="quick_controls_subtitle" msgid="1667408093326318053">"आफ्ना जोडिएका यन्त्रहरूका लागि नियन्त्रण सुविधाहरू थप्नुहोस्"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्र नियन्त्रण गर्ने विजेटहरू सेटअप गर्नुहोस्"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"आफ्ना नियन्त्रणहरूमाथि पहुँच राख्न पावर बटन थिचिराख्नुहोस्"</string>
- <string name="controls_providers_title" msgid="6879775889857085056">"नियन्त्रणहरू थप्न अनुप्रयोग छनौट गर्नुहोस्"</string>
+ <string name="controls_providers_title" msgid="6879775889857085056">"नियन्त्रणहरू थप्न एप छनौट गर्नुहोस्"</string>
<plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
<item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> वटा नियन्त्र थपियो।</item>
<item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियन्त्र थपियो</item>
@@ -1047,7 +1041,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"थप हेर्न स्वाइप गर्नुहोस्"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string>
<string name="controls_media_close_session" msgid="9023534788828414585">"यो मिडिया सत्र बन्द गर्नुहोस्"</string>
- <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, अनुप्रयोग जाँच गर्नु…"</string>
+ <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
<string name="controls_error_failed" msgid="960228639198558525">"त्रुटि भयो, फेरि प्रयास गर्नु…"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"कार्य हुँदै छ"</string>
<string name="controls_added_tooltip" msgid="4842812921719153085">"नयाँ नियन्त्रण सुविधाहरू हेर्न पावर बटन थिचिराख्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index cde084f3d27e..8acd97cbf003 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -32,12 +32,12 @@
<string name="invalid_charger" msgid="4370074072117767416">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ। ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍‌କୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍‌କୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
- <string name="battery_low_why" msgid="2056750982959359863">"ସେଟିଙ୍ଗ"</string>
+ <string name="battery_low_why" msgid="2056750982959359863">"ସେଟିଂସ୍"</string>
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଚାଲୁ କରିବେ?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"ବ୍ୟାଟେରୀ ସେଭର୍ ବିଷୟରେ"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ଅନ୍‌ କରନ୍ତୁ"</string>
<string name="battery_saver_start_action" msgid="4553256017945469937">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍ କରନ୍ତୁ"</string>
- <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ସେଟିଙ୍ଗ"</string>
+ <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ସେଟିଂସ୍"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"ୱାଇ-ଫାଇ"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ଅଟୋ-ରୋଟେଟ୍‌ ସ୍କ୍ରିନ୍"</string>
<string name="status_bar_settings_mute_label" msgid="914392730086057522">"ମ୍ୟୁଟ୍"</string>
@@ -91,7 +91,7 @@
<string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବେ?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"ରେକର୍ଡିଂ ସମୟରେ, Android ସିଷ୍ଟମ୍ ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ଚାଲୁଥିବା ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନାକୁ କ୍ୟାପଚର୍ କରିପାରିବ। ଏହା ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ, ମେସେଜଗୁଡ଼ିକ ଏବଂ ଅଡିଓ ଅନ୍ତର୍ଭୁକ୍ତ କରେ।"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"ରେକର୍ଡିଂ ସମୟରେ, Android ସିଷ୍ଟମ୍ ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ଚାଲୁଥିବା ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନାକୁ କ୍ୟାପଚର୍ କରିପାରିବ। ଏଥିରେ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ, ମେସେଜ ଏବଂ ଅଡିଓ ଅନ୍ତର୍ଭୁକ୍ତ।"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"ଅଡିଓ ରେକର୍ଡ କରନ୍ତୁ"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"ଡିଭାଇସ୍ ଅଡିଓ"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ, ଯେପରିକି ସଙ୍ଗୀତ, କଲ୍ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ"</string>
@@ -241,7 +241,7 @@
<string name="accessibility_battery_level" msgid="5143715405241138822">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା।"</string>
<string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ଶତକଡ଼ା।"</string>
- <string name="accessibility_settings_button" msgid="2197034218538913880">"ସିଷ୍ଟମ୍‍ ସେଟିଙ୍ଗ।"</string>
+ <string name="accessibility_settings_button" msgid="2197034218538913880">"ସିଷ୍ଟମ୍‍ ସେଟିଂସ୍।"</string>
<string name="accessibility_notifications_button" msgid="3960913924189228831">"ବିଜ୍ଞପ୍ତି"</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ସମସ୍ତ ବିଜ୍ଞପ୍ତି ଦେଖନ୍ତୁ"</string>
<string name="accessibility_remove_notification" msgid="1641455251495815527">"ବିଜ୍ଞପ୍ତି ଖାଲି କରନ୍ତୁ।"</string>
@@ -256,9 +256,9 @@
<skip />
<string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା।"</string>
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ବିଜ୍ଞପ୍ତି ଶେଡ୍‍।"</string>
- <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ଦ୍ରୁତ ସେଟିଙ୍ଗ।"</string>
+ <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ଦ୍ରୁତ ସେଟିଂସ୍।"</string>
<string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌।"</string>
- <string name="accessibility_desc_settings" msgid="6728577365389151969">"ସେଟିଙ୍ଗ"</string>
+ <string name="accessibility_desc_settings" msgid="6728577365389151969">"ସେଟିଂସ୍"</string>
<string name="accessibility_desc_recent_apps" msgid="1748675199348914194">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀ"</string>
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ୱର୍କ ଲକ୍‍ ସ୍କ୍ରୀନ୍‍"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -328,8 +328,8 @@
<item quantity="one">ଭିତରେ ଆଉ <xliff:g id="NUMBER_0">%s</xliff:g>ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ରହିଛି।</item>
</plurals>
<string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"ବିଜ୍ଞପ୍ତି ସେଟିଙ୍ଗ"</string>
- <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> ସେଟିଙ୍ଗ"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"ବିଜ୍ଞପ୍ତି ସେଟିଂସ୍"</string>
+ <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> ସେଟିଂସ୍"</string>
<string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"ସ୍କ୍ରୀନ୍‍ ସ୍ୱଚାଳିତ ଭାବେ ବୁଲିବ।"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍‌ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ପୋର୍ଟ୍ରେଟ୍‍ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
@@ -355,7 +355,7 @@
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ଅନ୍ ହେଉଛି…"</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"ଉଜ୍ଜ୍ୱଳତା"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ସ୍ୱତଃ-ଘୂର୍ଣ୍ଣନ"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ୍"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ୍ ସ୍କ୍ରିନ୍"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> ମୋଡ୍‍"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"ଘୂର୍ଣ୍ଣନ ଲକ୍‍ ହୋଇଛି"</string>
@@ -367,11 +367,11 @@
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"ମିଡିଆ ଡିଭାଇସ୍‌"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
<string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"କେବଳ ଜରୁରୀକାଳୀନ କଲ୍‌"</string>
- <string name="quick_settings_settings_label" msgid="2214639529565474534">"ସେଟିଙ୍ଗ"</string>
+ <string name="quick_settings_settings_label" msgid="2214639529565474534">"ସେଟିଂସ୍"</string>
<string name="quick_settings_time_label" msgid="3352680970557509303">"ସମୟ"</string>
<string name="quick_settings_user_label" msgid="1253515509432672496">"ମୁଁ"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"ୟୁଜର୍‌"</string>
- <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ନୂଆ ୟୁଜର୍‌"</string>
+ <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string>
<string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"ନେଟ୍‌ୱର୍କ ନାହିଁ"</string>
@@ -389,7 +389,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"ସ୍ୱଚାଳିତ"</string>
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"ରଙ୍ଗ ଇନଭାର୍ଟ୍ କରନ୍ତୁ"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"ରଙ୍ଗ ସଂଶୋଧନ ମୋଡ୍‍"</string>
- <string name="quick_settings_more_settings" msgid="2878235926753776694">"ଅଧିକ ସେଟିଙ୍ଗ"</string>
+ <string name="quick_settings_more_settings" msgid="2878235926753776694">"ଅଧିକ ସେଟିଂସ୍"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"ହୋଇଗଲା"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"ସଂଯୁକ୍ତ"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"କନେକ୍ଟ ରହିଛି, ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -471,8 +471,8 @@
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ, ବର୍ତ୍ତମାନର ୟୁଜର୍‍ ହେଉଛନ୍ତି <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"ବର୍ତ୍ତମାନର ୟୁଜର୍‍ ହେଉଛନ୍ତି <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ପ୍ରୋଫାଇଲ୍ ଦେଖାନ୍ତୁ"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ୟୁଜର୍‍ଙ୍କୁ ଯୋଡ଼ନ୍ତୁ"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ନୂତନ ୟୁଜର୍‍"</string>
+ <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ଅବଧିର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
@@ -486,7 +486,7 @@
<string name="user_logout_notification_title" msgid="3644848998053832589">"ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍‍ କରନ୍ତୁ"</string>
<string name="user_logout_notification_text" msgid="7441286737342997991">"ବର୍ତ୍ତମାନର ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍‍ କରନ୍ତୁ"</string>
<string name="user_logout_notification_action" msgid="7974458760719361881">"ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍‍ କରନ୍ତୁ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ୟୁଜର୍‍ ଯୋଡ଼ିବେ?"</string>
+ <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string>
<string name="user_add_user_message_short" msgid="2599370307878014791">"ଜଣେ ନୂଆ ୟୁଜର୍‍ଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍‍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ୟୁଜର୍‍ଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍‍ ଆପ୍‌ଗୁଡ଼ିକୁ ଅପଡେଟ୍‌ କରିପାରିବେ।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -558,7 +558,7 @@
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"ଆପଣ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ ଅଛନ୍ତି, ଯାହା ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ନେଟ୍‌ୱର୍କର ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
- <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string>
+ <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"ମୁକ୍ତ ବିଶ୍ୱସ୍ତ କ୍ରୀଡେନଶିଆଲ୍‍"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"ଆପଣଙ୍କ ଆଡମିନ୍‍ ନେଟ୍‌ୱର୍କ ଲଗଇନ୍‍ କରିବା ଅନ୍‍ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ଡିଭାଇସରେ ଟ୍ରାଫିକ୍‍ ନିରୀକ୍ଷଣ କରେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
@@ -579,7 +579,7 @@
<string name="hidden_notifications_setup" msgid="2064795578526982467">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="5901885672973736563">"ବର୍ତ୍ତମାନ ଅଫ୍‍ କରନ୍ତୁ"</string>
- <string name="accessibility_volume_settings" msgid="1458961116951564784">"ସାଉଣ୍ଡ ସେଟିଙ୍ଗ"</string>
+ <string name="accessibility_volume_settings" msgid="1458961116951564784">"ସାଉଣ୍ଡ ସେଟିଂସ୍"</string>
<string name="accessibility_volume_expand" msgid="7653070939304433603">"ବଢ଼ାନ୍ତୁ"</string>
<string name="accessibility_volume_collapse" msgid="2746845391013829996">"ଛୋଟ କରନ୍ତୁ"</string>
<string name="volume_odi_captions_tip" msgid="8825655463280990941">"ସ୍ବଚାଳିତ କ୍ୟାପ୍ସନ୍ ମିଡିଆ"</string>
@@ -610,7 +610,7 @@
<string name="stream_music" msgid="2188224742361847580">"ମିଡିଆ"</string>
<string name="stream_alarm" msgid="16058075093011694">"ଆଲାର୍ମ"</string>
<string name="stream_notification" msgid="7930294049046243939">"ବିଜ୍ଞପ୍ତି"</string>
- <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ବ୍ଲୁଟୂଥ୍‍‌"</string>
+ <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ବ୍ଲୁଟୁଥ୍‍‌"</string>
<string name="stream_dtmf" msgid="7322536356554673067">"ଡୁଆଲ୍‍ ମଲ୍ଟି ଟୋନ୍‍ ଫ୍ରିକ୍ୱେନ୍ସୀ"</string>
<string name="stream_accessibility" msgid="3873610336741987152">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="ring_toggle_title" msgid="5973120187287633224">"କଲ୍‌"</string>
@@ -726,12 +726,12 @@
<string name="appops_camera_overlay" msgid="6466845606058816484">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି।"</string>
<string name="appops_mic_overlay" msgid="4609326508944233061">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର କରୁଛି।"</string>
<string name="appops_camera_mic_overlay" msgid="5584311236445644095">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ଓ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି।"</string>
- <string name="notification_appops_settings" msgid="5208974858340445174">"ସେଟିଙ୍ଗ"</string>
+ <string name="notification_appops_settings" msgid="5208974858340445174">"ସେଟିଂସ୍"</string>
<string name="notification_appops_ok" msgid="2177609375872784124">"ଠିକ୍ ଅଛି"</string>
<string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ ଖୋଲା ଯାଇଛି"</string>
<string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ ବନ୍ଦ ହୋଇଛି"</string>
<string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"ଏହି ଚ୍ୟାନେଲରୁ ବିଜ୍ଞପ୍ତିକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="notification_more_settings" msgid="4936228656989201793">"ଅଧିକ ସେଟିଙ୍ଗ"</string>
+ <string name="notification_more_settings" msgid="4936228656989201793">"ଅଧିକ ସେଟିଂସ୍"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"କଷ୍ଟମାଇଜ୍‌ କରନ୍ତୁ"</string>
<string name="notification_done" msgid="6215117625922713976">"ହୋଇଗଲା"</string>
<string name="inline_undo" msgid="9026953267645116526">"ପୂର୍ବସ୍ଥାନକୁ ଫେରାଇଆଣନ୍ତୁ"</string>
@@ -811,7 +811,7 @@
<string name="battery" msgid="769686279459897127">"ବ୍ୟାଟେରୀ"</string>
<string name="clock" msgid="8978017607326790204">"ଘଣ୍ଟା"</string>
<string name="headset" msgid="4485892374984466437">"ହେଡସେଟ୍‍"</string>
- <string name="accessibility_long_click_tile" msgid="210472753156768705">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string>
+ <string name="accessibility_long_click_tile" msgid="210472753156768705">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string>
<string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"ହେଡଫୋନ୍‍ ସଂଯୁକ୍ତ"</string>
<string name="accessibility_status_bar_headset" msgid="2699275863720926104">"ହେଡସେଟ୍‍ ସଂଯୁକ୍ତ"</string>
<string name="data_saver" msgid="3484013368530820763">"ଡାଟା ସେଭର୍‍"</string>
@@ -888,9 +888,9 @@
<string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ଆପ୍‍ ସ୍ପ୍ଲିଟ୍‍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
<string name="forced_resizable_secondary_display" msgid="522558907654394940">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ କାମ ନକରିପାରେ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
- <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
+ <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
- <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ବନ୍ଦ କରନ୍ତୁ।"</string>
+ <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଂସ୍ ବନ୍ଦ କରନ୍ତୁ।"</string>
<string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ଆଲାର୍ମ ସେଟ୍‍।"</string>
<string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ଭାବରେ ସାଇନ୍‌ ଇନ୍‌ କରିଛନ୍ତି"</string>
<string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
@@ -903,7 +903,7 @@
<string name="pip_phone_expand" msgid="1424988917240616212">"ବଢ଼ାନ୍ତୁ"</string>
<string name="pip_phone_minimize" msgid="9057117033655996059">"ଛୋଟ କରନ୍ତୁ"</string>
<string name="pip_phone_close" msgid="8801864042095341824">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="pip_phone_settings" msgid="5687538631925004341">"ସେଟିଙ୍ଗ"</string>
+ <string name="pip_phone_settings" msgid="5687538631925004341">"ସେଟିଂସ୍"</string>
<string name="pip_phone_dismiss_hint" msgid="5825740708095316710">"ଖାରଜ କରିବାକୁ ତଳକୁ ଟାଣନ୍ତୁ"</string>
<string name="pip_menu_title" msgid="6365909306215631910">"ମେନୁ"</string>
<string name="pip_notification_title" msgid="8661573026059630525">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string>
@@ -976,7 +976,7 @@
<string name="no_auto_saver_action" msgid="7467924389609773835">"ନାହିଁ, ଥାଉ"</string>
<string name="auto_saver_enabled_title" msgid="4294726198280286333">"ଆଗରୁ ସେଟ୍‌ କରିଥିବା ସମୟ ଅନୁସାରେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହୋଇଛି"</string>
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"ଚାର୍ଜ <xliff:g id="PERCENTAGE">%d</xliff:g>%%ରୁ କମ୍‌ ହେଲେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଆପେ ଅନ୍‌ ହୋଇଯିବ।"</string>
- <string name="open_saver_setting_action" msgid="2111461909782935190">"ସେଟିଙ୍ଗ"</string>
+ <string name="open_saver_setting_action" msgid="2111461909782935190">"ସେଟିଂସ୍"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ବୁଝିଗଲି"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ସେନ୍ସର୍‍ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string>
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାନ୍ତୁ"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଦେଖାନ୍ତୁ"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ଆପଗୁଡ଼ିକ ଉପରେ ଫ୍ଲୋଟିଂ ବବଲ୍ ପରି ଦେଖାଯିବ"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\' ମୋଡରେ ବାଧା ଉପୁଯାଇପାରିବ"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ବୁଝିଗଲି"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ଓଭର୍‌ଲେ ୱିଣ୍ଡୋ"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 4e6247acd3ab..4602968b1151 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਦੇ ਸਿਖਰ \'ਤੇ ਦਿਖਾਓ"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਦਿਖਾਓ"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ਐਪਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਫਲੋਟਿੰਗ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ਸਮਝ ਲਿਆ"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਓਵਰਲੇ Window"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window ਦੇ ਕੰਟਰੋਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index e577fd2cf5ac..4caf6ae5abb2 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -90,7 +90,7 @@
<string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
- <string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć rejestrowanie?"</string>
+ <string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć nagrywanie?"</string>
<string name="screenrecord_description" msgid="1123231719680353736">"Podczas nagrywania system Android może rejestrować wszelkie informacji poufne wyświetlane na ekranie lub odtwarzane na urządzeniu. Dotyczy to m.in. haseł, szczegółów płatności, zdjęć, wiadomości i odtwarzanych dźwięków."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagraj dźwięk"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki odtwarzane na urządzeniu"</string>
@@ -108,7 +108,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anuluj"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
<string name="screenrecord_delete_label" msgid="1376347010553987058">"Usuń"</string>
- <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano rejestrowanie zawartości ekranu"</string>
+ <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano nagrywanie zawartości ekranu"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć"</string>
<string name="screenrecord_delete_description" msgid="1604522770162810570">"Usunięto nagranie zawartości ekranu"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Kliknij Zarządzaj, aby wyłączyć dymki z tej aplikacji"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – ustawienia"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9a7f8174bc4b..db7dc624d842 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -101,7 +101,7 @@
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"A gravar o ecrã…"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"A gravar o ecrã e o áudio…"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques no ecrã"</string>
- <string name="screenrecord_stop_text" msgid="6549288689506057686">"Tocar para parar"</string>
+ <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toque para parar"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Parar"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"Colocar em pausa"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões em qualquer altura"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em Gerir para desativar os balões desta app."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Definições de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index dc5c682a9985..37896aaa14a8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -374,7 +374,7 @@
<string name="quick_settings_user_title" msgid="8673045967216204537">"Utilizator"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Utilizator nou"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
- <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neconectat"</string>
+ <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neconectată"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Nicio rețea"</string>
<string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi deconectat"</string>
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi activat"</string>
@@ -1004,8 +1004,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlați oricând baloanele"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Atingeți Gestionați pentru a dezactiva baloanele din această aplicație"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accesați Setările pentru a actualiza navigarea în sistem"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 1fde1e29a5e7..70083b037127 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"මෙම යෙදුමෙන් බුබුලු ක්‍රියාවිරහිත කිරීමට කළමනාකරණය කරන්න තට්ටු කරන්න"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"තේරුණා"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සැකසීම්"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7504f1510476..c71e4fa613e4 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ovládajte bubliny kedykoľvek"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Klepnutím na Spravovať vypnite bubliny z tejto aplikácie"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Dobre"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavenia upozornenia <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b4276015aa1f..d41b2a34727b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -33,10 +33,10 @@
<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>
<string name="battery_low_why" msgid="2056750982959359863">"Nastavitve"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite vklopiti varčevanje z energijo baterije?"</string>
+ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite vklopiti varčevanje z baterijo?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O varčevanju z energijo baterije"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Vklopi"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"Vklop varčevanja z energijo baterije"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"Vklop varčevanja z baterijo"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Nastavitve"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Samodejno zasukaj zaslon"</string>
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov kadar koli"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dotaknite se »Upravljanje«, da izklopite oblačke iz te aplikacije"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumem"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ae6089151c4b..bc07100c82c8 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -90,7 +90,7 @@
<string name="screenshot_preview_description" msgid="7606510140714080474">"Pamja paraprake e imazhit"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
- <string name="screenrecord_start_label" msgid="1750350278888217473">"Të niset regjistrimi?"</string>
+ <string name="screenrecord_start_label" msgid="1750350278888217473">"Të nis regjistrimi?"</string>
<string name="screenrecord_description" msgid="1123231719680353736">"Gjatë regjistrimit, sistemi Android mund të regjistrojë çdo informacion delikat që është i dukshëm në ekranin tënd ose që luhet në pajisje. Kjo përfshin fjalëkalimet, informacionin e pagesave, fotografitë, mesazhet dhe audion."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Regjistro audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audioja e pajisjes"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollo flluskat në çdo moment"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trokit \"Menaxho\" për të çaktivizuar flluskat nga ky aplikacion"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"E kuptova"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Cilësimet e <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index c32626c917cb..b01dc4fd21bf 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1004,8 +1004,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролишите облачиће у било ком тренутку"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Важи"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 6ef1dfdc3e7d..c7943980b0e8 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -91,7 +91,7 @@
<string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Vill du starta inspelningen?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"När du spelar kan Android-systemet registrera alla känsliga uppgifter som visas på skärmen eller spelas upp på enheten. Detta omfattar lösenord, betalningsuppgifter, foton, meddelanden och ljud."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"När du spelar in kan Android-systemet registrera alla känsliga uppgifter som visas på skärmen eller spelas upp på enheten. Detta omfattar lösenord, betalningsuppgifter, foton, meddelanden och ljud."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Spela in ljud"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Ljud på enheten"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Ljud från enheten, till exempel musik, samtal och ringsignaler"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bubblor när som helst"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryck på Hantera för att stänga av bubblor från den här appen"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Inställningar för <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Öppna inställningarna och uppdatera systemnavigeringen"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index a0e31d2ceafb..6951872bde02 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -87,8 +87,7 @@
<string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ஸ்கிரீன் ஷாட்டுகளை எடுப்பதை, ஆப்ஸ் அல்லது உங்கள் நிறுவனம் அனுமதிக்கவில்லை"</string>
<string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ஸ்கிரீன்ஷாட்டை நிராகரி"</string>
- <!-- no translation found for screenshot_preview_description (7606510140714080474) -->
- <skip />
+ <string name="screenshot_preview_description" msgid="7606510140714080474">"ஸ்கிரீன்ஷாட்டின் மாதிரிக்காட்சி"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"ரெக்கார்டிங்கைத் தொடங்கவா?"</string>
@@ -708,8 +707,7 @@
<string name="notification_bubble_title" msgid="8330481035191903164">"பபிள்"</string>
<string name="notification_channel_summary_low" msgid="7300447764759926720">"ஒலியோ அதிர்வோ இல்லாமல் முழு கவனம் செலுத்த உதவும்."</string>
<string name="notification_channel_summary_default" msgid="3539949463907902037">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும்."</string>
- <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) -->
- <skip />
+ <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும். <xliff:g id="APP_NAME">%1$s</xliff:g> இலிருந்து வரும் உரையாடல்கள் இயல்பாகவே குமிழ் வடிவில் தோன்றும்."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"இந்த உள்ளடக்கத்திற்கான மிதக்கும் ஷார்ட்கட் மூலம் உங்கள் கவனத்தைப் பெற்றிருக்கும்."</string>
<string name="notification_channel_summary_priority" msgid="7415770044553264622">"உரையாடல் பிரிவின் மேற்பகுதியில் ஒரு குமிழாகக் காட்டப்படும்."</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"அமைப்புகள்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index e74700923292..4d90e7866cd7 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్‌డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్‌ను అప్‌డేట్ చేయడానికి సెట్టింగ్‌లకు వెళ్లండి"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్‌బై"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"సంభాషణ విభాగంలో ఎగువున చూపబడుతుంది"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"లాక్ స్క్రీన్ మీద ప్రొఫైల్ ఫోటో చూపబడుతుంది"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"యాప్‌ల పైన తేలియాడే బబుల్‌లాగా కనిపిస్తాయి"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'అంతరాయం కలిగించవద్దు\' మోడ్‌కు అంతరాయం"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"అర్థమైంది"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"మాగ్నిఫికేషన్ ఓవర్‌లే విండో"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"మాగ్నిఫికేషన్ విండో"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"మాగ్నిఫికేషన్ నియంత్రణల విండో"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index bde22a53f15a..a51f62ee782a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ควบคุมบับเบิลได้ทุกเมื่อ"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"แตะ \"จัดการ\" เพื่อปิดบับเบิลจากแอปนี้"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"รับทราบ"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"การตั้งค่า <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index cafaaace6fdf..082b5c72ad0e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolin ang mga bubble anumang oras"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"I-tap ang Pamahalaan para i-off ang mga bubble mula sa app na ito"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Mga setting ng <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c9d53357caf6..d81066cb3c16 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Baloncukları istediğiniz zaman kontrol edin"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu uygulamanın baloncuklarını kapatmak için Yönet\'e dokunun"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 00e9d58dd06f..a6da1b4b2a18 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1009,8 +1009,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Налаштовуйте спливаючі чати будь-коли"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Натисніть \"Налаштувати\", щоб вимкнути спливаючі чати від цього додатка"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зрозуміло"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Налаштування параметра \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6cc8dd3f75c8..b9cc796434ff 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1004,16 +1004,11 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string>
- <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) -->
- <skip />
- <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) -->
- <skip />
- <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) -->
- <skip />
- <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) -->
- <skip />
- <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) -->
- <skip />
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"گفتگو کے سیکشن میں سب سے اوپر دکھائیں"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"مقفل سکرین پر پروفائل کی تصویر دکھائیں"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ایپس کے سب سے اوپر فلوٹنگ بلبلہ کے طور پر ظاہر ہوں"</string>
+ <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مداخلت کریں ڈسٹرب نہ کریں"</string>
+ <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"سمجھ آ گئی"</string>
<string name="magnification_overlay_title" msgid="6584179429612427958">"میگنیفیکیشن اوورلے ونڈو"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"میگنیفکیشن ونڈو کنٹرولز"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 43099f4f060d..b926d753b5db 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -508,7 +508,7 @@
<string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string>
<string name="notification_section_header_gentle" msgid="3044910806569985386">"Sokin bildirishnomalar"</string>
- <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalar bildirilishi"</string>
+ <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalarning yuborilishi"</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 qilingan"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c0996af8051b..ed8b3a556998 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát tùy chọn cài đặt bong bóng trò chuyện bất mọi lúc"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Nhấn vào nút Quản lý để tắt bong bóng trò chuyện từ ứng dụng này"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index fba35b2fe36e..6fe19c9efede 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"随时控制对话泡"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"点按“管理”按钮,可关闭来自此应用的对话泡"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>设置"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 3c0654292d94..9f4bf907ef98 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -97,7 +97,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"裝置播放的音效,例如音樂、通話和鈴聲"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"麥克風"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"裝置音訊和麥克風"</string>
- <string name="screenrecord_start" msgid="330991441575775004">"開始錄影"</string>
+ <string name="screenrecord_start" msgid="330991441575775004">"開始"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"正在錄影螢幕畫面"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"錄影螢幕畫面和音訊"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"顯示輕觸螢幕的位置"</string>
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"隨時控制小視窗設定"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕按「管理」即可關閉此應用程式的小視窗"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index de15aff3adc0..94990c79b829 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"你隨時可以控管對話框的各項設定"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕觸 [管理] 即可關閉來自這個應用程式的對話框"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"我知道了"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e9793422ebde..c9bef049e05e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -999,8 +999,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Lawula amabhamuza noma nini"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Thepha okuthi Phatha ukuvala amabhamuza kusuka kulolu hlelo lokusebenza"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ngiyezwa"</string>
- <!-- no translation found for bubbles_app_settings (5779443644062348657) -->
- <skip />
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> izilungiselelo"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 2e217a5e83ea..82eda311da6a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -246,10 +246,13 @@
<color name="control_list_popup_background">@*android:color/background_floating_material_dark</color>
<color name="control_spinner_dropdown">@*android:color/foreground_material_dark</color>
<color name="control_more_vert">@*android:color/foreground_material_dark</color>
- <color name="control_enabled_light_background">@color/GM2_yellow_200</color>
- <color name="control_enabled_thermo_heat_background">@color/GM2_red_200</color>
- <color name="control_enabled_thermo_cool_background">@color/GM2_blue_200</color>
- <color name="control_enabled_default_background">@color/GM2_blue_200</color>
+ <color name="control_enabled_light_background">#413C2D</color>
+ <color name="control_enabled_thermo_heat_background">#41312E</color>
+ <color name="control_enabled_thermo_cool_background">#303744</color>
+ <color name="control_enabled_default_background">#3C3D40</color>
+ <color name="control_enabled_heat_foreground">#FF8B66</color>
+ <color name="control_enabled_default_foreground">@color/GM2_blue_300</color>
+ <color name="control_enabled_cool_foreground">@color/GM2_blue_300</color>
<!-- Docked misalignment message -->
<color name="misalignment_text_color">#F28B82</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bad18cf67d98..eca25575d020 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -625,6 +625,15 @@
<!-- The height of the gap between adjacent notification sections. -->
<dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen>
+ <!-- Size of the face pile shown on one-line (children of a group) conversation notifications -->
+ <dimen name="conversation_single_line_face_pile_size">36dp</dimen>
+
+ <!-- Size of an avatar shown on one-line (children of a group) conversation notifications -->
+ <dimen name="conversation_single_line_avatar_size">24dp</dimen>
+
+ <!-- Border width for avatars in the face pile shown on one-line (children of a group) conversation notifications -->
+ <dimen name="conversation_single_line_face_pile_protection_width">1dp</dimen>
+
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 26ae79081491..304cf85487a2 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -475,7 +475,6 @@
<item name="android:textColor">?android:attr/textColorTertiary</item>
</style>
-
<style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
<item name="android:background">@drawable/btn_borderless_rect</item>
</style>
@@ -670,6 +669,7 @@
<item name="android:colorBackground">@android:color/black</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:statusBarColor">@*android:color/transparent</item>
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
</style>
<style name="TextAppearance.Control">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
index b8997c29dd52..ed9c98b47b08 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -257,12 +257,8 @@ public class PluginInstanceManager<T extends Plugin> {
if (DEBUG) Log.d(TAG, "queryAll " + mAction);
for (int i = mPlugins.size() - 1; i >= 0; i--) {
PluginInfo<T> plugin = mPlugins.get(i);
- mListener.onPluginDisconnected(plugin.mPlugin);
- if (!(plugin.mPlugin instanceof PluginFragment)) {
- // Only call onDestroy for plugins that aren't fragments, as fragments
- // will get the onDestroy as part of the fragment lifecycle.
- plugin.mPlugin.onDestroy();
- }
+ mMainHandler.obtainMessage(
+ mMainHandler.PLUGIN_DISCONNECTED, plugin).sendToTarget();
}
mPlugins.clear();
handleQueryPlugins(null);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 9e9b9dc4f3b0..dd5cc7c9bbd4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -38,7 +38,7 @@ public abstract class TaskStackChangeListener {
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
public void onActivityUnpinned() { }
public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) { }
+ boolean clearedTask, boolean wasVisible) { }
public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
public void onActivityDismissingDockedStack() { }
public void onActivityLaunchOnSecondaryDisplayFailed() { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index ce9cbabaa5e9..a76a901c5c81 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -122,11 +122,12 @@ public class TaskStackChangeListeners extends TaskStackListener {
@Override
public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) throws RemoteException {
+ boolean clearedTask, boolean wasVisible) throws RemoteException {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = task;
args.argi1 = homeTaskVisible ? 1 : 0;
args.argi2 = clearedTask ? 1 : 0;
+ args.argi3 = wasVisible ? 1 : 0;
mHandler.removeMessages(H.ON_ACTIVITY_RESTART_ATTEMPT);
mHandler.obtainMessage(H.ON_ACTIVITY_RESTART_ATTEMPT, args).sendToTarget();
}
@@ -305,9 +306,10 @@ public class TaskStackChangeListeners extends TaskStackListener {
final RunningTaskInfo task = (RunningTaskInfo) args.arg1;
final boolean homeTaskVisible = args.argi1 != 0;
final boolean clearedTask = args.argi2 != 0;
+ final boolean wasVisible = args.argi3 != 0;
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
mTaskStackListeners.get(i).onActivityRestartAttempt(task,
- homeTaskVisible, clearedTask);
+ homeTaskVisible, clearedTask, wasVisible);
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 1f27ae238533..73dfd32d03a2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -18,6 +18,8 @@ package com.android.systemui.accessibility;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
+import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
+
import android.accessibilityservice.AccessibilityService;
import android.app.PendingIntent;
import android.app.RemoteAction;
@@ -25,6 +27,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.graphics.drawable.Icon;
import android.hardware.input.InputManager;
import android.os.Handler;
@@ -32,6 +35,7 @@ import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
@@ -43,12 +47,15 @@ import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.R;
+import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.Dependency;
import com.android.systemui.SystemUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.statusbar.phone.StatusBar;
+import java.util.Locale;
+
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -58,7 +65,6 @@ import javax.inject.Singleton;
@Singleton
public class SystemActions extends SystemUI {
private static final String TAG = "SystemActions";
- // TODO(b/147916452): add implementation on launcher side to register this action.
/**
* Action ID to go back.
@@ -96,12 +102,6 @@ public class SystemActions extends SystemUI {
AccessibilityService.GLOBAL_ACTION_POWER_DIALOG; // = 6
/**
- * Action ID to toggle docking the current app's window
- */
- private static final int SYSTEM_ACTION_ID_TOGGLE_SPLIT_SCREEN =
- AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN; // = 7
-
- /**
* Action ID to lock the screen
*/
private static final int SYSTEM_ACTION_ID_LOCK_SCREEN =
@@ -114,13 +114,22 @@ public class SystemActions extends SystemUI {
AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT; // = 9
/**
- * Action ID to show accessibility menu
+ * Action ID to trigger the accessibility button
+ */
+ public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON =
+ AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON; // 11
+
+ /**
+ * Action ID to show accessibility button's menu of services
*/
- private static final int SYSTEM_ACTION_ID_ACCESSIBILITY_MENU = 10;
+ public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER =
+ AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; // 12
private Recents mRecents;
private StatusBar mStatusBar;
private SystemActionsBroadcastReceiver mReceiver;
+ private Locale mLocale;
+ private AccessibilityManager mA11yManager;
@Inject
public SystemActions(Context context) {
@@ -128,96 +137,139 @@ public class SystemActions extends SystemUI {
mRecents = Dependency.get(Recents.class);
mStatusBar = Dependency.get(StatusBar.class);
mReceiver = new SystemActionsBroadcastReceiver();
+ mLocale = mContext.getResources().getConfiguration().getLocales().get(0);
+ mA11yManager = (AccessibilityManager) mContext.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
}
@Override
public void start() {
mContext.registerReceiverForAllUsers(mReceiver, mReceiver.createIntentFilter(), null, null);
+ registerActions();
+ }
- // TODO(b/148087487): update the icon used below to a valid one
- RemoteAction actionBack = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_back_label),
- mContext.getString(R.string.accessibility_system_action_back_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_BACK));
- RemoteAction actionHome = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_home_label),
- mContext.getString(R.string.accessibility_system_action_home_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_HOME));
-
- RemoteAction actionRecents = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_recents_label),
- mContext.getString(R.string.accessibility_system_action_recents_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS));
-
- RemoteAction actionNotifications = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_notifications_label),
- mContext.getString(R.string.accessibility_system_action_notifications_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS));
-
- RemoteAction actionQuickSettings = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_quick_settings_label),
- mContext.getString(R.string.accessibility_system_action_quick_settings_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS));
-
- RemoteAction actionPowerDialog = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_power_dialog_label),
- mContext.getString(R.string.accessibility_system_action_power_dialog_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG));
-
- RemoteAction actionToggleSplitScreen = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_toggle_split_screen_label),
- mContext.getString(R.string.accessibility_system_action_toggle_split_screen_label),
- mReceiver.createPendingIntent(
- mContext,
- SystemActionsBroadcastReceiver.INTENT_ACTION_TOGGLE_SPLIT_SCREEN));
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ final Locale locale = mContext.getResources().getConfiguration().getLocales().get(0);
+ if (!locale.equals(mLocale)) {
+ mLocale = locale;
+ registerActions();
+ }
+ }
- RemoteAction actionLockScreen = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_lock_screen_label),
- mContext.getString(R.string.accessibility_system_action_lock_screen_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN));
+ private void registerActions() {
+ RemoteAction actionBack = createRemoteAction(
+ R.string.accessibility_system_action_back_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_BACK);
+
+ RemoteAction actionHome = createRemoteAction(
+ R.string.accessibility_system_action_home_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_HOME);
+
+ RemoteAction actionRecents = createRemoteAction(
+ R.string.accessibility_system_action_recents_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS);
+
+ RemoteAction actionNotifications = createRemoteAction(
+ R.string.accessibility_system_action_notifications_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS);
+
+ RemoteAction actionQuickSettings = createRemoteAction(
+ R.string.accessibility_system_action_quick_settings_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS);
+
+ RemoteAction actionPowerDialog = createRemoteAction(
+ R.string.accessibility_system_action_power_dialog_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG);
+
+ RemoteAction actionLockScreen = createRemoteAction(
+ R.string.accessibility_system_action_lock_screen_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN);
+
+ RemoteAction actionTakeScreenshot = createRemoteAction(
+ R.string.accessibility_system_action_screenshot_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT);
+
+ mA11yManager.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK);
+ mA11yManager.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME);
+ mA11yManager.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS);
+ mA11yManager.registerSystemAction(actionNotifications, SYSTEM_ACTION_ID_NOTIFICATIONS);
+ mA11yManager.registerSystemAction(actionQuickSettings, SYSTEM_ACTION_ID_QUICK_SETTINGS);
+ mA11yManager.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG);
+ mA11yManager.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN);
+ mA11yManager.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT);
+ }
- RemoteAction actionTakeScreenshot = new RemoteAction(
- Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_screenshot_label),
- mContext.getString(R.string.accessibility_system_action_screenshot_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT));
+ /**
+ * Register a system action.
+ * @param actionId the action ID to register.
+ */
+ public void register(int actionId) {
+ int labelId;
+ String intent;
+ switch (actionId) {
+ case SYSTEM_ACTION_ID_BACK:
+ labelId = R.string.accessibility_system_action_back_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_BACK;
+ break;
+ case SYSTEM_ACTION_ID_HOME:
+ labelId = R.string.accessibility_system_action_home_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_HOME;
+ break;
+ case SYSTEM_ACTION_ID_RECENTS:
+ labelId = R.string.accessibility_system_action_recents_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS;
+ break;
+ case SYSTEM_ACTION_ID_NOTIFICATIONS:
+ labelId = R.string.accessibility_system_action_notifications_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS;
+ break;
+ case SYSTEM_ACTION_ID_QUICK_SETTINGS:
+ labelId = R.string.accessibility_system_action_quick_settings_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS;
+ break;
+ case SYSTEM_ACTION_ID_POWER_DIALOG:
+ labelId = R.string.accessibility_system_action_power_dialog_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG;
+ break;
+ case SYSTEM_ACTION_ID_LOCK_SCREEN:
+ labelId = R.string.accessibility_system_action_lock_screen_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN;
+ break;
+ case SYSTEM_ACTION_ID_TAKE_SCREENSHOT:
+ labelId = R.string.accessibility_system_action_screenshot_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT;
+ break;
+ case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON:
+ labelId = R.string.accessibility_system_action_accessibility_button_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON;
+ break;
+ case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER:
+ labelId = R.string.accessibility_system_action_accessibility_button_chooser_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER;
+ break;
+ default:
+ return;
+ }
+ mA11yManager.registerSystemAction(createRemoteAction(labelId, intent), actionId);
+ }
- RemoteAction actionAccessibilityMenu = new RemoteAction(
+ private RemoteAction createRemoteAction(int labelId, String intent) {
+ // TODO(b/148087487): update the icon used below to a valid one
+ return new RemoteAction(
Icon.createWithResource(mContext, R.drawable.ic_info),
- mContext.getString(R.string.accessibility_system_action_accessibility_menu_label),
- mContext.getString(R.string.accessibility_system_action_accessibility_menu_label),
- mReceiver.createPendingIntent(
- mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_MENU));
-
- AccessibilityManager am = (AccessibilityManager) mContext.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
+ mContext.getString(labelId),
+ mContext.getString(labelId),
+ mReceiver.createPendingIntent(mContext, intent));
+ }
- am.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK);
- am.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME);
- am.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS);
- am.registerSystemAction(actionNotifications, SYSTEM_ACTION_ID_NOTIFICATIONS);
- am.registerSystemAction(actionQuickSettings, SYSTEM_ACTION_ID_QUICK_SETTINGS);
- am.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG);
- am.registerSystemAction(actionToggleSplitScreen, SYSTEM_ACTION_ID_TOGGLE_SPLIT_SCREEN);
- am.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN);
- am.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT);
- am.registerSystemAction(actionAccessibilityMenu, SYSTEM_ACTION_ID_ACCESSIBILITY_MENU);
+ /**
+ * Unregister a system action.
+ * @param actionId the action ID to unregister.
+ */
+ public void unregister(int actionId) {
+ mA11yManager.unregisterSystemAction(actionId);
}
private void handleBack() {
@@ -266,10 +318,6 @@ public class SystemActions extends SystemUI {
}
}
- private void handleToggleSplitScreen() {
- mStatusBar.toggleSplitScreen();
- }
-
private void handleLockScreen() {
IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService();
@@ -288,11 +336,19 @@ public class SystemActions extends SystemUI {
SCREENSHOT_GLOBAL_ACTIONS, new Handler(Looper.getMainLooper()), null);
}
- private void handleAccessibilityMenu() {
+ private void handleAccessibilityButton() {
AccessibilityManager.getInstance(mContext).notifyAccessibilityButtonClicked(
Display.DEFAULT_DISPLAY);
}
+ private void handleAccessibilityButtonChooser() {
+ final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
+ intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ }
+
private class SystemActionsBroadcastReceiver extends BroadcastReceiver {
private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK";
private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME";
@@ -300,12 +356,12 @@ public class SystemActions extends SystemUI {
private static final String INTENT_ACTION_NOTIFICATIONS = "SYSTEM_ACTION_NOTIFICATIONS";
private static final String INTENT_ACTION_QUICK_SETTINGS = "SYSTEM_ACTION_QUICK_SETTINGS";
private static final String INTENT_ACTION_POWER_DIALOG = "SYSTEM_ACTION_POWER_DIALOG";
- private static final String INTENT_ACTION_TOGGLE_SPLIT_SCREEN =
- "SYSTEM_ACTION_TOGGLE_SPLIT_SCREEN";
private static final String INTENT_ACTION_LOCK_SCREEN = "SYSTEM_ACTION_LOCK_SCREEN";
private static final String INTENT_ACTION_TAKE_SCREENSHOT = "SYSTEM_ACTION_TAKE_SCREENSHOT";
- private static final String INTENT_ACTION_ACCESSIBILITY_MENU =
- "SYSTEM_ACTION_ACCESSIBILITY_MENU";
+ private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON =
+ "SYSTEM_ACTION_ACCESSIBILITY_BUTTON";
+ private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER =
+ "SYSTEM_ACTION_ACCESSIBILITY_BUTTON_MENU";
private PendingIntent createPendingIntent(Context context, String intentAction) {
switch (intentAction) {
@@ -315,10 +371,10 @@ public class SystemActions extends SystemUI {
case INTENT_ACTION_NOTIFICATIONS:
case INTENT_ACTION_QUICK_SETTINGS:
case INTENT_ACTION_POWER_DIALOG:
- case INTENT_ACTION_TOGGLE_SPLIT_SCREEN:
case INTENT_ACTION_LOCK_SCREEN:
case INTENT_ACTION_TAKE_SCREENSHOT:
- case INTENT_ACTION_ACCESSIBILITY_MENU: {
+ case INTENT_ACTION_ACCESSIBILITY_BUTTON:
+ case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: {
Intent intent = new Intent(intentAction);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
@@ -336,10 +392,10 @@ public class SystemActions extends SystemUI {
intentFilter.addAction(INTENT_ACTION_NOTIFICATIONS);
intentFilter.addAction(INTENT_ACTION_QUICK_SETTINGS);
intentFilter.addAction(INTENT_ACTION_POWER_DIALOG);
- intentFilter.addAction(INTENT_ACTION_TOGGLE_SPLIT_SCREEN);
intentFilter.addAction(INTENT_ACTION_LOCK_SCREEN);
intentFilter.addAction(INTENT_ACTION_TAKE_SCREENSHOT);
- intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_MENU);
+ intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON);
+ intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER);
return intentFilter;
}
@@ -371,10 +427,6 @@ public class SystemActions extends SystemUI {
handlePowerDialog();
break;
}
- case INTENT_ACTION_TOGGLE_SPLIT_SCREEN: {
- handleToggleSplitScreen();
- break;
- }
case INTENT_ACTION_LOCK_SCREEN: {
handleLockScreen();
break;
@@ -383,8 +435,12 @@ public class SystemActions extends SystemUI {
handleTakeScreenshot();
break;
}
- case INTENT_ACTION_ACCESSIBILITY_MENU: {
- handleAccessibilityMenu();
+ case INTENT_ACTION_ACCESSIBILITY_BUTTON: {
+ handleAccessibilityButton();
+ break;
+ }
+ case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: {
+ handleAccessibilityButtonChooser();
break;
}
default:
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4d7eb758f733..e8fd7e0e8b38 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -669,8 +669,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mStackView.onThemeChanged();
}
mBubbleIconFactory = new BubbleIconFactory(mContext);
+ // Reload each bubble
for (Bubble b: mBubbleData.getBubbles()) {
- // Reload each bubble
+ b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
+ }
+ for (Bubble b: mBubbleData.getOverflowBubbles()) {
b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
}
}
@@ -1236,7 +1239,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Override
public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) {
+ boolean clearedTask, boolean wasVisible) {
for (Bubble b : mBubbleData.getBubbles()) {
if (b.getDisplayId() == task.displayId) {
expandStackAndSelectBubble(b.getKey());
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 9a2ccb52132b..25271e18806f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -16,6 +16,8 @@
package com.android.systemui.controls.management
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Intent
@@ -163,7 +165,23 @@ class ControlsFavoritingActivity @Inject constructor(
pageIndicator.visibility =
if (listOfStructures.size > 1) View.VISIBLE else View.GONE
- ControlsAnimations.enterAnimation(pageIndicator).start()
+ ControlsAnimations.enterAnimation(pageIndicator).apply {
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ // Position the tooltip if necessary after animations are complete
+ // so we can get the position on screen. The tooltip is not
+ // rooted in the layout root.
+ if (pageIndicator.visibility == View.VISIBLE &&
+ mTooltipManager != null) {
+ val p = IntArray(2)
+ pageIndicator.getLocationOnScreen(p)
+ val x = p[0] + pageIndicator.width / 2
+ val y = p[1] + pageIndicator.height
+ mTooltipManager?.show(R.string.controls_structure_tooltip, x, y)
+ }
+ }
+ })
+ }.start()
ControlsAnimations.enterAnimation(structurePager).start()
}
}, Consumer { runnable -> cancelLoadRunnable = runnable })
@@ -225,27 +243,6 @@ class ControlsFavoritingActivity @Inject constructor(
}
pageIndicator = requireViewById<ManagementPageIndicator>(
R.id.structure_page_indicator).apply {
- addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
- override fun onLayoutChange(
- v: View,
- left: Int,
- top: Int,
- right: Int,
- bottom: Int,
- oldLeft: Int,
- oldTop: Int,
- oldRight: Int,
- oldBottom: Int
- ) {
- if (v.visibility == View.VISIBLE && mTooltipManager != null) {
- val p = IntArray(2)
- v.getLocationOnScreen(p)
- val x = p[0] + (right - left) / 2
- val y = p[1] + bottom - top
- mTooltipManager?.show(R.string.controls_structure_tooltip, x, y)
- }
- }
- })
visibilityListener = {
if (it != View.VISIBLE) {
mTooltipManager?.hide(true)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 5be2f221ebcb..ba053a83ccbd 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -58,7 +58,7 @@ class ControlViewHolder(
companion object {
const val STATE_ANIMATION_DURATION = 700L
private const val UPDATE_DELAY_IN_MILLIS = 3000L
- private const val ALPHA_ENABLED = (255.0 * 0.2).toInt()
+ private const val ALPHA_ENABLED = 255
private const val ALPHA_DISABLED = 0
private val FORCE_PANEL_DEVICES = setOf(
DeviceTypes.TYPE_THERMOSTAT,
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 42db0051b8e6..f3693c1c72ab 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -536,7 +536,7 @@ class ControlsUiControllerImpl @Inject constructor (
override fun hide() {
Log.d(ControlsUiController.TAG, "hide()")
hidden = true
- popup?.dismiss()
+ popup?.dismissImmediate()
activeDialog?.dismiss()
ControlActionCoordinator.closeDialog()
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 18bfd899a4e7..490890f263aa 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -159,6 +159,15 @@ public class DozeMachine {
mDozeHost = dozeHost;
}
+ /**
+ * Clean ourselves up.
+ */
+ public void destroy() {
+ for (Part part : mParts) {
+ part.destroy();
+ }
+ }
+
/** Initializes the set of {@link Part}s. Must be called exactly once after construction. */
public void setParts(Part[] parts) {
Preconditions.checkState(mParts == null);
@@ -411,6 +420,9 @@ public class DozeMachine {
/** Dump current state. For debugging only. */
default void dump(PrintWriter pw) {}
+
+ /** Give the Part a chance to clean itself up. */
+ default void destroy() {}
}
/** A wrapper interface for {@link android.service.dreams.DreamService} */
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 700a8611c8bd..10776c91df84 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -164,6 +164,17 @@ public class DozeSensors {
}
/**
+ * Unregister any sensors.
+ */
+ public void destroy() {
+ // Unregisters everything, which is enough to allow gc.
+ for (TriggerSensor triggerSensor : mSensors) {
+ triggerSensor.setListening(false);
+ }
+ mProximitySensor.pause();
+ }
+
+ /**
* Temporarily disable some sensors to avoid turning on the device while the user is
* turning it off.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 7cbbdd783e74..529b016aaca6 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -65,6 +65,7 @@ public class DozeService extends DreamService
mPluginManager.removePluginListener(this);
}
super.onDestroy();
+ mDozeMachine.destroy();
mDozeMachine = null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b3299916356c..1be4d438683a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -111,6 +111,11 @@ public class DozeTriggers implements DozeMachine.Part {
mBroadcastDispatcher = broadcastDispatcher;
}
+ @Override
+ public void destroy() {
+ mDozeSensors.destroy();
+ }
+
private void onNotification(Runnable onPulseSuppressedListener) {
if (DozeMachine.DEBUG) {
Log.d(TAG, "requestNotificationPulse");
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 6aa4f8684928..9bd32ff7b344 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -484,8 +484,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
*/
@VisibleForTesting
protected int getMaxShownPowerItems() {
- // TODO: Overflow disabled on keyguard while we solve for touch blocking issues.
- if (shouldUseControlsLayout() && !mKeyguardShowing) {
+ if (shouldUseControlsLayout()) {
return mResources.getInteger(com.android.systemui.R.integer.power_menu_max_columns);
} else {
return Integer.MAX_VALUE;
@@ -2246,7 +2245,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mShowing = false;
resetOrientation();
dismissPanel();
- dismissOverflow();
+ dismissOverflow(true);
if (mControlsUiController != null) mControlsUiController.hide();
mNotificationShadeWindowController.setForceHasTopUi(mHadTopUi);
mDepthController.updateGlobalDialogVisibility(0, null /* view */);
@@ -2259,9 +2258,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
}
- private void dismissOverflow() {
+ private void dismissOverflow(boolean immediate) {
if (mOverflowPopup != null) {
- mOverflowPopup.dismiss();
+ if (immediate) {
+ mOverflowPopup.dismissImmediate();
+ } else {
+ mOverflowPopup.dismiss();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1012a5213a58..b26dc5f91245 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1717,9 +1717,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
resetKeyguardDonePendingLocked();
}
- mUpdateMonitor.clearBiometricRecognized();
if (mGoingToSleep) {
+ mUpdateMonitor.clearBiometricRecognized();
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
return;
}
@@ -1740,6 +1740,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
}
handleHide();
+ mUpdateMonitor.clearBiometricRecognized();
Trace.endSection();
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index f6bd948fe11b..ddc9c9d7c314 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -247,7 +247,7 @@ public class MediaControlPanel {
// Try to find a browser service component for this app
// TODO also check for a media button receiver intended for restarting (b/154127084)
// Only check if we haven't tried yet or the session token changed
- String pkgName = mController.getPackageName();
+ final String pkgName = mController.getPackageName();
if (mServiceComponent == null && !mCheckedForResumption) {
Log.d(TAG, "Checking for service component");
PackageManager pm = mContext.getPackageManager();
@@ -283,18 +283,22 @@ public class MediaControlPanel {
// Transfer chip
mSeamless = mMediaNotifView.findViewById(R.id.media_seamless);
- if (mSeamless != null && mLocalMediaManager != null) {
- mSeamless.setVisibility(View.VISIBLE);
- updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
- mSeamless.setOnClickListener(v -> {
- final Intent intent = new Intent()
- .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
- .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
- mController.getPackageName())
- .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
- mActivityStarter.startActivity(intent, false, true /* dismissShade */,
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- });
+ if (mSeamless != null) {
+ if (mLocalMediaManager != null) {
+ mSeamless.setVisibility(View.VISIBLE);
+ updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
+ mSeamless.setOnClickListener(v -> {
+ final Intent intent = new Intent()
+ .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
+ .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+ mController.getPackageName())
+ .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
+ mActivityStarter.startActivity(intent, false, true /* dismissShade */,
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ });
+ } else {
+ Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName);
+ }
}
makeActive();
@@ -556,6 +560,7 @@ public class MediaControlPanel {
deviceName.setText(device.getName());
} else {
// Reset to default
+ Log.d(TAG, "device is null. Not binding output chip.");
iconView.setVisibility(View.GONE);
deviceName.setText(com.android.internal.R.string.ext_media_seamless_action);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 78975735ef0f..a86a884c8016 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -135,8 +135,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
@Override
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
- boolean homeTaskVisible, boolean clearedTask) {
- if (task.configuration.windowConfiguration.getWindowingMode()
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
!= WINDOWING_MODE_PINNED) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 6c5312d57b2a..fae8af4f575a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -708,15 +708,15 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mActiveMediaSessionListener, null);
updateMediaController(mMediaSessionManager.getActiveSessions(null));
for (int i = mListeners.size() - 1; i >= 0; i--) {
- mListeners.get(i).onPipEntered();
+ mListeners.get(i).onPipEntered(packageName);
}
updatePipVisibility(true);
}
@Override
public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) {
- if (task.configuration.windowConfiguration.getWindowingMode()
+ boolean clearedTask, boolean wasVisible) {
+ if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
!= WINDOWING_MODE_PINNED) {
return;
}
@@ -758,7 +758,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
* because there's no guarantee for the PIP manager be return relavent information
* correctly. (e.g. {@link isPipShown}).
*/
- void onPipEntered();
+ void onPipEntered(String packageName);
/** Invoked when a PIPed activity is closed. */
void onPipActivityClosed();
/** Invoked when the PIP menu gets shown. */
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index c7e77ccfa488..158be45e0adb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -137,8 +137,8 @@ public class PipMenuActivity extends Activity implements PipManager.Listener {
}
@Override
- public void onPipEntered() {
- if (DEBUG) Log.d(TAG, "onPipEntered()");
+ public void onPipEntered(String packageName) {
+ if (DEBUG) Log.d(TAG, "onPipEntered(), packageName=" + packageName);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
index b01c2f4eb5fb..30ec29683942 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -23,6 +23,8 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -50,6 +52,8 @@ public class PipNotification {
private static final String ACTION_MENU = "PipNotification.menu";
private static final String ACTION_CLOSE = "PipNotification.close";
+ private final PackageManager mPackageManager;
+
private final PipManager mPipManager;
private final NotificationManager mNotificationManager;
@@ -59,13 +63,16 @@ public class PipNotification {
private String mDefaultTitle;
private int mDefaultIconResId;
+ /** Package name for the application that owns PiP window. */
+ private String mPackageName;
private boolean mNotified;
- private String mTitle;
+ private String mMediaTitle;
private Bitmap mArt;
private PipManager.Listener mPipListener = new PipManager.Listener() {
@Override
- public void onPipEntered() {
+ public void onPipEntered(String packageName) {
+ mPackageName = packageName;
updateMediaControllerMetadata();
notifyPipNotification();
}
@@ -73,6 +80,7 @@ public class PipNotification {
@Override
public void onPipActivityClosed() {
dismissPipNotification();
+ mPackageName = null;
}
@Override
@@ -88,6 +96,7 @@ public class PipNotification {
@Override
public void onMoveToFullscreen() {
dismissPipNotification();
+ mPackageName = null;
}
@Override
@@ -146,6 +155,8 @@ public class PipNotification {
public PipNotification(Context context, BroadcastDispatcher broadcastDispatcher,
PipManager pipManager) {
+ mPackageManager = context.getPackageManager();
+
mNotificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
@@ -188,7 +199,7 @@ public class PipNotification {
.setShowWhen(true)
.setWhen(System.currentTimeMillis())
.setSmallIcon(mDefaultIconResId)
- .setContentTitle(!TextUtils.isEmpty(mTitle) ? mTitle : mDefaultTitle);
+ .setContentTitle(getNotificationTitle());
if (mArt != null) {
mNotificationBuilder.setStyle(new Notification.BigPictureStyle()
.bigPicture(mArt));
@@ -220,14 +231,36 @@ public class PipNotification {
}
}
}
- if (!TextUtils.equals(title, mTitle) || art != mArt) {
- mTitle = title;
+ if (!TextUtils.equals(title, mMediaTitle) || art != mArt) {
+ mMediaTitle = title;
mArt = art;
return true;
}
return false;
}
+ private String getNotificationTitle() {
+ if (!TextUtils.isEmpty(mMediaTitle)) {
+ return mMediaTitle;
+ }
+
+ final String applicationTitle = getApplicationLabel(mPackageName);
+ if (!TextUtils.isEmpty(applicationTitle)) {
+ return applicationTitle;
+ }
+
+ return mDefaultTitle;
+ }
+
+ private String getApplicationLabel(String packageName) {
+ try {
+ final ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0);
+ return mPackageManager.getApplicationLabel(appInfo).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ }
+
private static PendingIntent createPendingIntent(Context context, String action) {
return PendingIntent.getBroadcast(context, 0,
new Intent(action), PendingIntent.FLAG_CANCEL_CURRENT);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index c7ce1af0c1fb..cb3d5116a9cd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -343,6 +343,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
return;
}
+ if (desc == null || desc.getTitle() == null) {
+ Log.e(TAG, "Description incomplete");
+ return;
+ }
+
Log.d(TAG, "adding track from browser: " + desc + ", " + component);
QSMediaPlayer player = new QSMediaPlayer(mContext, QSPanel.this,
null, mForegroundExecutor, mBackgroundExecutor, mActivityStarter);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 8051998e2530..f3e2f104621e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -20,8 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.trust.TrustManager;
@@ -39,7 +37,6 @@ import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -66,22 +63,6 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation {
private TrustManager mTrustManager;
private OverviewProxyService mOverviewProxyService;
- private TaskStackChangeListener mListener = new TaskStackChangeListener() {
- @Override
- public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
- boolean homeTaskVisible, boolean clearedTask) {
- if (task.configuration.windowConfiguration.getWindowingMode()
- != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mDividerOptional.isPresent()) {
- return;
- }
-
- final Divider divider = mDividerOptional.get();
- if (divider.isMinimized()) {
- divider.onUndockingTask();
- }
- }
- };
-
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy,
@@ -96,7 +77,6 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation {
mHandler = new Handler();
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mListener);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 70454d4d63df..290816b7e8af 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -48,7 +48,6 @@ import android.graphics.Region;
import android.graphics.drawable.Icon;
import android.media.MediaActionSound;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -188,7 +187,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private final ImageView mDismissImage;
private Bitmap mScreenBitmap;
+ private SaveImageInBackgroundTask mSaveInBgTask;
private Animator mScreenshotAnimation;
+ private Runnable mOnCompleteRunnable;
private boolean mInDarkMode = false;
private float mScreenshotOffsetXPx;
@@ -197,8 +198,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private float mDismissButtonSize;
private float mCornerSizeX;
- private AsyncTask<Void, Void, Void> mSaveInBgTask;
-
private MediaActionSound mCameraSound;
// standard material ease
@@ -211,6 +210,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
case MESSAGE_CORNER_TIMEOUT:
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_INTERACTION_TIMEOUT);
GlobalScreenshot.this.clearScreenshot("timeout");
+ mOnCompleteRunnable.run();
break;
default:
break;
@@ -252,6 +252,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mDismissButton.setOnClickListener(view -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
clearScreenshot("dismiss_button");
+ mOnCompleteRunnable.run();
});
mDismissImage = mDismissButton.findViewById(R.id.global_screenshot_dismiss_image);
@@ -325,19 +326,19 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
data.createDeleteAction = false;
+
if (mSaveInBgTask != null) {
- mSaveInBgTask.cancel(false);
+ mSaveInBgTask.ignoreResult();
}
- mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data).execute();
+ mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data);
+ mSaveInBgTask.execute();
}
/**
* Takes a screenshot of the current display and shows an animation.
*/
private void takeScreenshot(Consumer<Uri> finisher, Rect crop) {
- clearScreenshot("new screenshot requested");
-
int rot = mDisplay.getRotation();
int width = crop.width();
int height = crop.height();
@@ -349,10 +350,12 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private void takeScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect) {
mScreenBitmap = screenshot;
+
if (mScreenBitmap == null) {
mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
finisher.accept(null);
+ mOnCompleteRunnable.run();
return;
}
@@ -366,11 +369,13 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
// Start the post-screenshot animation
- startAnimation(finisher, screenRect.width(), screenRect.height(),
- screenRect);
+ startAnimation(finisher, screenRect.width(), screenRect.height(), screenRect);
}
- void takeScreenshot(Consumer<Uri> finisher) {
+ void takeScreenshot(Consumer<Uri> finisher, Runnable onComplete) {
+ clearScreenshot("new screenshot requested");
+ mOnCompleteRunnable = onComplete;
+
mDisplay.getRealMetrics(mDisplayMetrics);
takeScreenshot(
finisher,
@@ -378,9 +383,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
}
void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds,
- Insets visibleInsets, int taskId, Consumer<Uri> finisher) {
+ Insets visibleInsets, int taskId, Consumer<Uri> finisher, Runnable onComplete) {
// TODO use taskId and visibleInsets
clearScreenshot("new screenshot requested");
+ mOnCompleteRunnable = onComplete;
+
takeScreenshot(screenshot, finisher, screenshotScreenBounds);
}
@@ -388,7 +395,10 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
* Displays a screenshot selector
*/
@SuppressLint("ClickableViewAccessibility")
- void takeScreenshotPartial(final Consumer<Uri> finisher) {
+ void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) {
+ clearScreenshot("new screenshot requested");
+ mOnCompleteRunnable = onComplete;
+
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() {
@Override
@@ -660,6 +670,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
() -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED);
clearScreenshot("chip tapped");
+ mOnCompleteRunnable.run();
});
mActionsView.addView(actionChip);
}
@@ -671,6 +682,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
shareChip.setPendingIntent(imageData.shareAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED);
clearScreenshot("chip tapped");
+ mOnCompleteRunnable.run();
});
mActionsView.addView(shareChip);
@@ -681,6 +693,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
editChip.setPendingIntent(imageData.editAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED);
clearScreenshot("chip tapped");
+ mOnCompleteRunnable.run();
});
mActionsView.addView(editChip);
@@ -689,6 +702,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
imageData.editAction.actionIntent.send();
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
clearScreenshot("screenshot preview tapped");
+ mOnCompleteRunnable.run();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Intent cancelled", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 170174deaeb3..bc3c33d68b67 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -130,11 +130,6 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
Resources r = mContext.getResources();
try {
- CompletableFuture<List<Notification.Action>> smartActionsFuture =
- ScreenshotSmartActions.getSmartActionsFuture(
- mScreenshotId, mImageFileName, image, mSmartActionsProvider,
- mSmartActionsEnabled, isManagedProfile(mContext));
-
// Save the screenshot to the MediaStore
final ContentValues values = new ContentValues();
values.put(MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES
@@ -148,6 +143,11 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture =
+ ScreenshotSmartActions.getSmartActionsFuture(
+ mScreenshotId, uri, image, mSmartActionsProvider,
+ mSmartActionsEnabled, isManagedProfile(mContext));
+
try {
// First, write the actual data for our screenshot
try (OutputStream out = resolver.openOutputStream(uri)) {
@@ -203,7 +203,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
1000);
smartActions.addAll(buildSmartActions(
ScreenshotSmartActions.getSmartActions(
- mScreenshotId, mImageFileName, smartActionsFuture, timeoutMs,
+ mScreenshotId, smartActionsFuture, timeoutMs,
mSmartActionsProvider),
mContext));
}
@@ -230,6 +230,19 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
return null;
}
+ /**
+ * If we get a new screenshot request while this one is saving, we want to continue saving in
+ * the background but not return anything.
+ */
+ void ignoreResult() {
+ mParams.mActionsReadyListener = new GlobalScreenshot.ActionsReadyListener() {
+ @Override
+ void onActionsReady(GlobalScreenshot.SavedImageData imageData) {
+ // do nothing
+ }
+ };
+ }
+
@Override
protected void onCancelled(Void params) {
// If we are cancelled while the task is running in the background, we may get null
@@ -311,6 +324,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
editIntent.setData(uri);
editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Make sure pending intents for the system user are still unique across users
// by setting the (otherwise unused) request code to the current user id.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
index 09a0644159e2..3edb33da9cd0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot;
import android.app.Notification;
import android.content.ComponentName;
import android.graphics.Bitmap;
+import android.net.Uri;
import android.util.Log;
import java.util.Collections;
@@ -67,7 +68,7 @@ public class ScreenshotNotificationSmartActionsProvider {
*/
public CompletableFuture<List<Notification.Action>> getActions(
String screenshotId,
- String screenshotFileName,
+ Uri screenshotUri,
Bitmap bitmap,
ComponentName componentName,
boolean isManagedProfile) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
index d31344446fac..c228fe2c4334 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
@@ -23,6 +23,7 @@ import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
+import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Slog;
@@ -45,7 +46,7 @@ public class ScreenshotSmartActions {
@VisibleForTesting
static CompletableFuture<List<Notification.Action>> getSmartActionsFuture(
- String screenshotId, String screenshotFileName, Bitmap image,
+ String screenshotId, Uri screenshotUri, Bitmap image,
ScreenshotNotificationSmartActionsProvider smartActionsProvider,
boolean smartActionsEnabled, boolean isManagedProfile) {
if (!smartActionsEnabled) {
@@ -70,7 +71,7 @@ public class ScreenshotSmartActions {
? runningTask.topActivity
: new ComponentName("", "");
smartActionsFuture = smartActionsProvider.getActions(
- screenshotId, screenshotFileName, image, componentName, isManagedProfile);
+ screenshotId, screenshotUri, image, componentName, isManagedProfile);
} catch (Throwable e) {
long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
@@ -84,7 +85,7 @@ public class ScreenshotSmartActions {
}
@VisibleForTesting
- static List<Notification.Action> getSmartActions(String screenshotId, String screenshotFileName,
+ static List<Notification.Action> getSmartActions(String screenshotId,
CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs,
ScreenshotNotificationSmartActionsProvider smartActionsProvider) {
long startTimeMs = SystemClock.uptimeMillis();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index f68cb745e4c8..98030d45b05e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -16,6 +16,9 @@
package com.android.systemui.screenshot;
+import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE;
+import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_URI;
+
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -51,8 +54,15 @@ public class TakeScreenshotService extends Service {
@Override
public void handleMessage(Message msg) {
final Messenger callback = msg.replyTo;
- Consumer<Uri> finisher = uri -> {
- Message reply = Message.obtain(null, 1, uri);
+ Consumer<Uri> uriConsumer = uri -> {
+ Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri);
+ try {
+ callback.send(reply);
+ } catch (RemoteException e) {
+ }
+ };
+ Runnable onComplete = () -> {
+ Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE);
try {
callback.send(reply);
} catch (RemoteException e) {
@@ -64,7 +74,8 @@ public class TakeScreenshotService extends Service {
// animation and error notification.
if (!mUserManager.isUserUnlocked()) {
Log.w(TAG, "Skipping screenshot because storage is locked!");
- post(() -> finisher.accept(null));
+ post(() -> uriConsumer.accept(null));
+ post(onComplete);
return;
}
@@ -79,19 +90,19 @@ public class TakeScreenshotService extends Service {
switch (msg.what) {
case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:
if (useCornerFlow) {
- mScreenshot.takeScreenshot(finisher);
+ mScreenshot.takeScreenshot(uriConsumer, onComplete);
} else {
mScreenshotLegacy.takeScreenshot(
- finisher, screenshotRequest.getHasStatusBar(),
+ uriConsumer, screenshotRequest.getHasStatusBar(),
screenshotRequest.getHasNavBar());
}
break;
case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION:
if (useCornerFlow) {
- mScreenshot.takeScreenshotPartial(finisher);
+ mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);
} else {
mScreenshotLegacy.takeScreenshotPartial(
- finisher, screenshotRequest.getHasStatusBar(),
+ uriConsumer, screenshotRequest.getHasStatusBar(),
screenshotRequest.getHasNavBar());
}
break;
@@ -102,10 +113,10 @@ public class TakeScreenshotService extends Service {
int taskId = screenshotRequest.getTaskId();
if (useCornerFlow) {
mScreenshot.handleImageAsScreenshot(
- screenshot, screenBounds, insets, taskId, finisher);
+ screenshot, screenBounds, insets, taskId, uriConsumer, onComplete);
} else {
mScreenshotLegacy.handleImageAsScreenshot(
- screenshot, screenBounds, insets, taskId, finisher);
+ screenshot, screenBounds, insets, taskId, uriConsumer);
}
break;
default:
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index b71c4ebb5930..f36f8c131848 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -21,23 +21,25 @@ import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
-import android.os.RemoteException;
import android.provider.Settings;
import android.util.Slog;
-import android.window.TaskOrganizer;
-import android.window.WindowContainerToken;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
@@ -48,6 +50,8 @@ import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.TransactionPool;
import com.android.systemui.recents.Recents;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.wm.DisplayChangeController;
import com.android.systemui.wm.DisplayController;
@@ -415,6 +419,21 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
private final DividerImeController mImePositionProcessor = new DividerImeController();
+ private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() {
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mSplits.isSplitScreenSupported()) {
+ return;
+ }
+
+ if (isMinimized()) {
+ onUndockingTask();
+ }
+ }
+ };
+
public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
DisplayController displayController, SystemWindows systemWindows,
DisplayImeController imeController, Handler handler,
@@ -485,6 +504,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
removeDivider();
return;
}
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mActivityRestartListener);
update(mDisplayController.getDisplayContext(displayId).getResources().getConfiguration());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 12298817d5a6..2647c04ff586 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -19,11 +19,13 @@ import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS;
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -182,7 +184,7 @@ public class NotificationLockscreenUserManagerImpl implements
protected final Context mContext;
private final Handler mMainHandler;
protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
- protected final ArrayList<UserInfo> mCurrentManagedProfiles = new ArrayList<>();
+ protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>();
protected int mCurrentUserId = 0;
protected NotificationPresenter mPresenter;
@@ -351,7 +353,10 @@ public class NotificationLockscreenUserManagerImpl implements
boolean exceedsPriorityThreshold;
if (NotificationUtils.useNewInterruptionModel(mContext)
&& hideSilentNotificationsOnLockscreen()) {
- exceedsPriorityThreshold = entry.getBucket() != BUCKET_SILENT;
+ exceedsPriorityThreshold =
+ entry.getBucket() == BUCKET_MEDIA_CONTROLS
+ || (entry.getBucket() != BUCKET_SILENT
+ && entry.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT);
} else {
exceedsPriorityThreshold = !entry.getRanking().isAmbient();
}
@@ -425,8 +430,9 @@ public class NotificationLockscreenUserManagerImpl implements
*/
public boolean allowsManagedPrivateNotificationsInPublic() {
synchronized (mLock) {
- for (UserInfo profile : mCurrentManagedProfiles) {
- if (!userAllowsPrivateNotificationsInPublic(profile.id)) {
+ for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) {
+ if (!userAllowsPrivateNotificationsInPublic(
+ mCurrentManagedProfiles.valueAt(i).id)) {
return false;
}
}
@@ -490,15 +496,22 @@ public class NotificationLockscreenUserManagerImpl implements
public boolean needsRedaction(NotificationEntry ent) {
int userId = ent.getSbn().getUserId();
- boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
- boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId);
- boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction;
+ boolean isCurrentUserRedactingNotifs =
+ !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
+ boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId);
+ boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId);
+
+ // redact notifications if the current user is redacting notifications; however if the
+ // notification is associated with a managed profile, we rely on the managed profile
+ // setting to determine whether to redact it
+ boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs)
+ || isNotifUserRedacted;
boolean notificationRequestsRedaction =
ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE;
boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey());
- return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen;
+ return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted;
}
private boolean packageHasVisibilityOverride(String key) {
@@ -519,7 +532,7 @@ public class NotificationLockscreenUserManagerImpl implements
for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
mCurrentProfiles.put(user.id, user);
if (UserManager.USER_TYPE_PROFILE_MANAGED.equals(user.userType)) {
- mCurrentManagedProfiles.add(user);
+ mCurrentManagedProfiles.put(user.id, user);
}
}
}
@@ -551,7 +564,7 @@ public class NotificationLockscreenUserManagerImpl implements
public boolean isAnyManagedProfilePublicMode() {
synchronized (mLock) {
for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) {
- if (isLockscreenPublicMode(mCurrentManagedProfiles.get(i).id)) {
+ if (isLockscreenPublicMode(mCurrentManagedProfiles.valueAt(i).id)) {
return true;
}
}
@@ -668,8 +681,8 @@ public class NotificationLockscreenUserManagerImpl implements
}
pw.print(" mCurrentManagedProfiles=");
synchronized (mLock) {
- for (UserInfo userInfo : mCurrentManagedProfiles) {
- pw.print("" + userInfo.id + " ");
+ for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) {
+ pw.print("" + mCurrentManagedProfiles.valueAt(i).id + " ");
}
}
pw.println();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index ec17f4ed868c..9738bcc69279 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -34,12 +34,13 @@ import com.android.systemui.statusbar.notification.stack.NotificationSectionsMan
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_HEADS_UP
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
+
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.policy.HeadsUpManager
import dagger.Lazy
-import java.util.Comparator
-import java.util.Objects
+import java.util.Objects;
import javax.inject.Inject
+import kotlin.Comparator
private const val TAG = "NotifRankingManager"
@@ -90,19 +91,13 @@ open class NotificationRankingManager @Inject constructor(
val aIsHighPriority = a.isHighPriority()
val bIsHighPriority = b.isHighPriority()
-
when {
aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
// Provide consistent ranking with headsUpManager
aHeadsUp -> headsUpManager.compare(a, b)
- usePeopleFiltering && aPersonType != bPersonType -> when (aPersonType) {
- TYPE_IMPORTANT_PERSON -> -1
- TYPE_PERSON -> when (bPersonType) {
- TYPE_IMPORTANT_PERSON -> 1
- else -> -1
- }
- else -> 1
- }
+
+ usePeopleFiltering && aPersonType != bPersonType ->
+ peopleNotificationIdentifier.compareTo(aPersonType, bPersonType)
// Upsort current media notification.
aMedia != bMedia -> if (aMedia) -1 else 1
// Upsort PRIORITY_MAX system notifications
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
index 5879c15c2493..d36627fb849d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
@@ -20,6 +20,7 @@ import android.annotation.IntDef
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.StatusBarNotification
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
@@ -33,21 +34,28 @@ interface PeopleNotificationIdentifier {
/**
* Identifies if the given notification can be classified as a "People" notification.
*
- * @return [TYPE_NON_PERSON] if not a people notification, [TYPE_PERSON] if a standard people
- * notification, and [TYPE_IMPORTANT_PERSON] if an "important" people notification.
+ * @return [TYPE_NON_PERSON] if not a people notification, [TYPE_PERSON] if it is a people
+ * notification that doesn't use shortcuts, [TYPE_FULL_PERSON] if it is a person notification
+ * that users shortcuts, and [TYPE_IMPORTANT_PERSON] if an "important" people notification
+ * that users shortcuts.
*/
@PeopleNotificationType
fun getPeopleNotificationType(sbn: StatusBarNotification, ranking: Ranking): Int
+ fun compareTo(@PeopleNotificationType a: Int,
+ @PeopleNotificationType b: Int): Int
+
companion object {
@Retention(AnnotationRetention.SOURCE)
- @IntDef(prefix = ["TYPE_"], value = [TYPE_NON_PERSON, TYPE_PERSON, TYPE_IMPORTANT_PERSON])
+ @IntDef(prefix = ["TYPE_"], value = [TYPE_NON_PERSON, TYPE_PERSON, TYPE_FULL_PERSON,
+ TYPE_IMPORTANT_PERSON])
annotation class PeopleNotificationType
const val TYPE_NON_PERSON = 0
const val TYPE_PERSON = 1
- const val TYPE_IMPORTANT_PERSON = 2
+ const val TYPE_FULL_PERSON = 2
+ const val TYPE_IMPORTANT_PERSON = 3
}
}
@@ -69,6 +77,11 @@ class PeopleNotificationIdentifierImpl @Inject constructor(
}
}
+ override fun compareTo(@PeopleNotificationType a: Int,
+ @PeopleNotificationType b: Int): Int {
+ return b.compareTo(a);
+ }
+
/**
* Given two [PeopleNotificationType]s, determine the upper bound. Used to constrain a
* notification to a type given multiple signals, i.e. notification groups, where each child
@@ -84,8 +97,9 @@ class PeopleNotificationIdentifierImpl @Inject constructor(
private val Ranking.personTypeInfo
get() = when {
!isConversation -> TYPE_NON_PERSON
+ shortcutInfo == null -> TYPE_PERSON
channel?.isImportantConversation == true -> TYPE_IMPORTANT_PERSON
- else -> TYPE_PERSON
+ else -> TYPE_FULL_PERSON
}
private fun extractPersonTypeInfo(sbn: StatusBarNotification) =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index ba72e2879f14..a9bb416cbebb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -535,6 +535,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return isNonblockable;
}
+ private boolean isConversation() {
+ return mPeopleNotificationIdentifier
+ .getPeopleNotificationType(mEntry.getSbn(), mEntry.getRanking())
+ != PeopleNotificationIdentifier.TYPE_NON_PERSON;
+ }
+
public void onNotificationUpdated() {
for (NotificationContentView l : mLayouts) {
l.onNotificationUpdated(mEntry);
@@ -547,7 +553,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mMenuRow.setAppName(mAppName);
}
if (mIsSummaryWithChildren) {
- mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
+ mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation());
mChildrenContainer.onNotificationUpdated();
}
if (mIconAnimationRunning) {
@@ -2349,8 +2355,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mIsSummaryWithChildren = mChildrenContainer != null
&& mChildrenContainer.getNotificationChildCount() > 0;
if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) {
- mChildrenContainer.recreateNotificationHeader(mExpandClickListener
- );
+ mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation());
}
getShowingLayout().updateBackgroundColor(false /* animate */);
mPrivateLayout.updateExpandButtons(isExpandable());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
new file mode 100644
index 000000000000..32477a6f39b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.Icon;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.widget.ConversationLayout;
+import com.android.systemui.R;
+
+/**
+ * A hybrid view which may contain information about one ore more conversations.
+ */
+public class HybridConversationNotificationView extends HybridNotificationView {
+
+ private ImageView mConversationIconView;
+ private TextView mConversationSenderName;
+ private View mConversationFacePile;
+ private int mConversationIconSize;
+ private int mFacePileSize;
+ private int mFacePileProtectionWidth;
+
+ public HybridConversationNotificationView(Context context) {
+ this(context, null);
+ }
+
+ public HybridConversationNotificationView(Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public HybridConversationNotificationView(
+ Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public HybridConversationNotificationView(
+ Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mConversationIconView = requireViewById(com.android.internal.R.id.conversation_icon);
+ mConversationFacePile = requireViewById(com.android.internal.R.id.conversation_face_pile);
+ mConversationSenderName = requireViewById(R.id.conversation_notification_sender);
+ mFacePileSize = getResources()
+ .getDimensionPixelSize(R.dimen.conversation_single_line_face_pile_size);
+ mConversationIconSize = getResources()
+ .getDimensionPixelSize(R.dimen.conversation_single_line_avatar_size);
+ mFacePileProtectionWidth = getResources().getDimensionPixelSize(
+ R.dimen.conversation_single_line_face_pile_protection_width);
+ mTransformationHelper.addViewTransformingToSimilar(mConversationIconView);
+ }
+
+ @Override
+ public void bind(@Nullable CharSequence title, @Nullable CharSequence text,
+ @Nullable View contentView) {
+ if (!(contentView instanceof ConversationLayout)) {
+ super.bind(title, text, contentView);
+ return;
+ }
+
+ ConversationLayout conversationLayout = (ConversationLayout) contentView;
+ Icon conversationIcon = conversationLayout.getConversationIcon();
+ if (conversationIcon != null) {
+ mConversationFacePile.setVisibility(GONE);
+ mConversationIconView.setVisibility(VISIBLE);
+ mConversationIconView.setImageIcon(conversationIcon);
+ } else {
+ // If there isn't an icon, generate a "face pile" based on the sender avatars
+ mConversationIconView.setVisibility(GONE);
+ mConversationFacePile.setVisibility(VISIBLE);
+
+ mConversationFacePile =
+ requireViewById(com.android.internal.R.id.conversation_face_pile);
+ ImageView facePileBottomBg = mConversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_bottom_background);
+ ImageView facePileBottom = mConversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_bottom);
+ ImageView facePileTop = mConversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_top);
+ conversationLayout.bindFacePile(facePileBottomBg, facePileBottom, facePileTop);
+ setSize(mConversationFacePile, mFacePileSize);
+ setSize(facePileBottom, mConversationIconSize);
+ setSize(facePileTop, mConversationIconSize);
+ setSize(facePileBottomBg, mConversationIconSize + 2 * mFacePileProtectionWidth);
+ mTransformationHelper.addViewTransformingToSimilar(facePileTop);
+ mTransformationHelper.addViewTransformingToSimilar(facePileBottom);
+ mTransformationHelper.addViewTransformingToSimilar(facePileBottomBg);
+ }
+ CharSequence conversationTitle = conversationLayout.getConversationTitle();
+ if (TextUtils.isEmpty(conversationTitle)) {
+ conversationTitle = title;
+ }
+ if (conversationLayout.isOneToOne()) {
+ mConversationSenderName.setVisibility(GONE);
+ } else {
+ mConversationSenderName.setVisibility(VISIBLE);
+ mConversationSenderName.setText(conversationLayout.getConversationSenderName());
+ }
+ CharSequence conversationText = conversationLayout.getConversationText();
+ if (TextUtils.isEmpty(conversationText)) {
+ conversationText = text;
+ }
+ super.bind(conversationTitle, conversationText, conversationLayout);
+ }
+
+ private static void setSize(View view, int size) {
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams();
+ lp.width = size;
+ lp.height = size;
+ view.setLayoutParams(lp);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
index fe819574f3b6..0ccebc130b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
@@ -16,18 +16,20 @@
package com.android.systemui.statusbar.notification.row;
+import android.annotation.Nullable;
import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
+import android.service.notification.StatusBarNotification;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.internal.widget.ConversationLayout;
import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.NotificationDozeHelper;
-import com.android.systemui.statusbar.notification.NotificationUtils;
/**
* A class managing hybrid groups that include {@link HybridNotificationView} and the notification
@@ -36,41 +38,41 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
public class HybridGroupManager {
private final Context mContext;
- private final ViewGroup mParent;
private float mOverflowNumberSize;
private int mOverflowNumberPadding;
private int mOverflowNumberColor;
- public HybridGroupManager(Context ctx, ViewGroup parent) {
+ public HybridGroupManager(Context ctx) {
mContext = ctx;
- mParent = parent;
initDimens();
}
public void initDimens() {
Resources res = mContext.getResources();
- mOverflowNumberSize = res.getDimensionPixelSize(
- R.dimen.group_overflow_number_size);
- mOverflowNumberPadding = res.getDimensionPixelSize(
- R.dimen.group_overflow_number_padding);
+ mOverflowNumberSize = res.getDimensionPixelSize(R.dimen.group_overflow_number_size);
+ mOverflowNumberPadding = res.getDimensionPixelSize(R.dimen.group_overflow_number_padding);
}
- private HybridNotificationView inflateHybridViewWithStyle(int style) {
+ private HybridNotificationView inflateHybridViewWithStyle(int style,
+ View contentView, ViewGroup parent) {
LayoutInflater inflater = new ContextThemeWrapper(mContext, style)
.getSystemService(LayoutInflater.class);
- HybridNotificationView hybrid = (HybridNotificationView) inflater.inflate(
- R.layout.hybrid_notification, mParent, false);
- mParent.addView(hybrid);
+ int layout = contentView instanceof ConversationLayout
+ ? R.layout.hybrid_conversation_notification
+ : R.layout.hybrid_notification;
+ HybridNotificationView hybrid = (HybridNotificationView)
+ inflater.inflate(layout, parent, false);
+ parent.addView(hybrid);
return hybrid;
}
- private TextView inflateOverflowNumber() {
+ private TextView inflateOverflowNumber(ViewGroup parent) {
LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
TextView numberView = (TextView) inflater.inflate(
- R.layout.hybrid_overflow_number, mParent, false);
- mParent.addView(numberView);
+ R.layout.hybrid_overflow_number, parent, false);
+ parent.addView(numberView);
updateOverFlowNumberColor(numberView);
return numberView;
}
@@ -87,22 +89,26 @@ public class HybridGroupManager {
}
public HybridNotificationView bindFromNotification(HybridNotificationView reusableView,
- Notification notification) {
- return bindFromNotificationWithStyle(reusableView, notification,
- R.style.HybridNotification);
+ View contentView, StatusBarNotification notification,
+ ViewGroup parent) {
+ return bindFromNotificationWithStyle(reusableView, contentView, notification,
+ R.style.HybridNotification, parent);
}
private HybridNotificationView bindFromNotificationWithStyle(
- HybridNotificationView reusableView, Notification notification, int style) {
+ HybridNotificationView reusableView, View contentView,
+ StatusBarNotification notification,
+ int style, ViewGroup parent) {
if (reusableView == null) {
- reusableView = inflateHybridViewWithStyle(style);
+ reusableView = inflateHybridViewWithStyle(style, contentView, parent);
}
- CharSequence titleText = resolveTitle(notification);
- CharSequence contentText = resolveText(notification);
- reusableView.bind(titleText, contentText);
+ CharSequence titleText = resolveTitle(notification.getNotification());
+ CharSequence contentText = resolveText(notification.getNotification());
+ reusableView.bind(titleText, contentText, contentView);
return reusableView;
}
+ @Nullable
private CharSequence resolveText(Notification notification) {
CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
if (contentText == null) {
@@ -111,6 +117,7 @@ public class HybridGroupManager {
return contentText;
}
+ @Nullable
private CharSequence resolveTitle(Notification notification) {
CharSequence titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
if (titleText == null) {
@@ -119,9 +126,10 @@ public class HybridGroupManager {
return titleText;
}
- public TextView bindOverflowNumber(TextView reusableView, int number) {
+ public TextView bindOverflowNumber(TextView reusableView, int number,
+ ViewGroup parent) {
if (reusableView == null) {
- reusableView = inflateOverflowNumber();
+ reusableView = inflateOverflowNumber(parent);
}
String text = mContext.getResources().getString(
R.string.notification_group_overflow_indicator, number);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
index be25d6377912..207144931c3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
@@ -36,8 +36,7 @@ import com.android.systemui.statusbar.notification.TransformState;
public class HybridNotificationView extends AlphaOptimizedLinearLayout
implements TransformableView {
- private ViewTransformationHelper mTransformationHelper;
-
+ protected final ViewTransformationHelper mTransformationHelper = new ViewTransformationHelper();
protected TextView mTitleView;
protected TextView mTextView;
@@ -69,9 +68,8 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mTitleView = (TextView) findViewById(R.id.notification_title);
- mTextView = (TextView) findViewById(R.id.notification_text);
- mTransformationHelper = new ViewTransformationHelper();
+ mTitleView = findViewById(R.id.notification_title);
+ mTextView = findViewById(R.id.notification_text);
mTransformationHelper.setCustomTransformation(
new ViewTransformationHelper.CustomTransformation() {
@Override
@@ -106,11 +104,8 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout
mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TEXT, mTextView);
}
- public void bind(CharSequence title) {
- bind(title, null);
- }
-
- public void bind(CharSequence title, CharSequence text) {
+ public void bind(@Nullable CharSequence title, @Nullable CharSequence text,
+ @Nullable View contentView) {
mTitleView.setText(title);
mTitleView.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE);
if (TextUtils.isEmpty(text)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index bd1745eaa028..f23f3bf28312 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -177,7 +177,7 @@ public class NotificationContentView extends FrameLayout {
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
- mHybridGroupManager = new HybridGroupManager(getContext(), this);
+ mHybridGroupManager = new HybridGroupManager(getContext());
mMediaTransferManager = new MediaTransferManager(getContext());
mSmartReplyConstants = Dependency.get(SmartReplyConstants.class);
mSmartReplyController = Dependency.get(SmartReplyController.class);
@@ -1163,7 +1163,7 @@ public class NotificationContentView extends FrameLayout {
if (mIsChildInGroup) {
boolean isNewView = mSingleLineView == null;
mSingleLineView = mHybridGroupManager.bindFromNotification(
- mSingleLineView, mStatusBarNotification.getNotification());
+ mSingleLineView, mContractedChild, mStatusBarNotification, this);
if (isNewView) {
updateViewVisibility(mVisibleType, VISIBLE_TYPE_SINGLELINE,
mSingleLineView, mSingleLineView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 13e7fe5cd6d8..15499b87d56d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -46,13 +46,13 @@ class NotificationConversationTemplateViewWrapper constructor(
)
private val conversationLayout: ConversationLayout = view as ConversationLayout
- private lateinit var conversationIcon: CachingIconView
+ private lateinit var conversationIconView: CachingIconView
private lateinit var conversationBadgeBg: View
private lateinit var expandButton: View
private lateinit var expandButtonContainer: View
private lateinit var imageMessageContainer: ViewGroup
private lateinit var messagingLinearLayout: MessagingLinearLayout
- private lateinit var conversationTitle: View
+ private lateinit var conversationTitleView: View
private lateinit var importanceRing: View
private lateinit var appName: View
private var facePileBottomBg: View? = null
@@ -63,7 +63,7 @@ class NotificationConversationTemplateViewWrapper constructor(
messagingLinearLayout = conversationLayout.messagingLinearLayout
imageMessageContainer = conversationLayout.imageMessageContainer
with(conversationLayout) {
- conversationIcon = requireViewById(com.android.internal.R.id.conversation_icon)
+ conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon)
conversationBadgeBg =
requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
expandButton = requireViewById(com.android.internal.R.id.expand_button)
@@ -71,7 +71,7 @@ class NotificationConversationTemplateViewWrapper constructor(
requireViewById(com.android.internal.R.id.expand_button_container)
importanceRing = requireViewById(com.android.internal.R.id.conversation_icon_badge_ring)
appName = requireViewById(com.android.internal.R.id.app_name_text)
- conversationTitle = requireViewById(com.android.internal.R.id.conversation_text)
+ conversationTitleView = requireViewById(com.android.internal.R.id.conversation_text)
facePileTop = findViewById(com.android.internal.R.id.conversation_face_pile_top)
facePileBottom = findViewById(com.android.internal.R.id.conversation_face_pile_bottom)
facePileBottomBg =
@@ -93,7 +93,7 @@ class NotificationConversationTemplateViewWrapper constructor(
addTransformedViews(
messagingLinearLayout,
appName,
- conversationTitle)
+ conversationTitleView)
// Let's ignore the image message container since that is transforming as part of the
// messages already
@@ -124,7 +124,7 @@ class NotificationConversationTemplateViewWrapper constructor(
)
addViewsTransformingToSimilar(
- conversationIcon,
+ conversationIconView,
conversationBadgeBg,
expandButton,
importanceRing,
@@ -136,29 +136,27 @@ class NotificationConversationTemplateViewWrapper constructor(
override fun setShelfIconVisible(visible: Boolean) {
if (conversationLayout.isImportantConversation) {
- if (conversationIcon.visibility != GONE) {
- conversationIcon.setForceHidden(visible);
+ if (conversationIconView.visibility != GONE) {
+ conversationIconView.isForceHidden = visible
// We don't want the small icon to be hidden by the extended wrapper, as force
// hiding the conversationIcon will already do that via its listener.
- return;
+ return
}
}
super.setShelfIconVisible(visible)
}
- override fun getShelfTransformationTarget(): View? {
- if (conversationLayout.isImportantConversation) {
- if (conversationIcon.visibility != GONE) {
- return conversationIcon
- } else {
- // A notification with a fallback icon was set to important. Currently
- // the transformation doesn't work for these and needs to be fixed. In the meantime
- // those are using the icon.
- return super.getShelfTransformationTarget();
- }
- }
- return super.getShelfTransformationTarget()
- }
+ override fun getShelfTransformationTarget(): View? =
+ if (conversationLayout.isImportantConversation)
+ if (conversationIconView.visibility != GONE)
+ conversationIconView
+ else
+ // A notification with a fallback icon was set to important. Currently
+ // the transformation doesn't work for these and needs to be fixed.
+ // In the meantime those are using the icon.
+ super.getShelfTransformationTarget()
+ else
+ super.getShelfTransformationTarget()
override fun setRemoteInputVisible(visible: Boolean) =
conversationLayout.showHistoricMessages(visible)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index e20be2b71939..f8b783113ccb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -27,11 +27,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.NotificationExpandButton;
+import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.TransformableView;
@@ -60,12 +62,14 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
private NotificationExpandButton mExpandButton;
protected NotificationHeaderView mNotificationHeader;
private TextView mHeaderText;
+ private TextView mAppNameText;
private ImageView mWorkProfileImage;
private View mCameraIcon;
private View mMicIcon;
private View mOverlayIcon;
private View mAppOps;
private View mAudiblyAlertedIcon;
+ private FrameLayout mIconContainer;
private boolean mIsLowPriority;
private boolean mTransformLowPriorityTitle;
@@ -108,8 +112,10 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
protected void resolveHeaderViews() {
+ mIconContainer = mView.findViewById(com.android.internal.R.id.header_icon_container);
mIcon = mView.findViewById(com.android.internal.R.id.icon);
mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
+ mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text);
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
@@ -182,6 +188,61 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
}
+ public void applyConversationSkin() {
+ if (mAppNameText != null) {
+ mAppNameText.setTextAppearance(
+ com.android.internal.R.style
+ .TextAppearance_DeviceDefault_Notification_Conversation_AppName);
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mAppNameText.getLayoutParams();
+ layoutParams.setMarginStart(0);
+ }
+ if (mIconContainer != null) {
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mIconContainer.getLayoutParams();
+ layoutParams.width =
+ mIconContainer.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.conversation_content_start);
+ final int marginStart =
+ mIconContainer.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_content_margin_start);
+ layoutParams.setMarginStart(marginStart * -1);
+ }
+ if (mIcon != null) {
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams();
+ layoutParams.setMarginEnd(0);
+ }
+ }
+
+ public void clearConversationSkin() {
+ if (mAppNameText != null) {
+ final int textAppearance = Utils.getThemeAttr(
+ mAppNameText.getContext(),
+ com.android.internal.R.attr.notificationHeaderTextAppearance,
+ com.android.internal.R.style.TextAppearance_DeviceDefault_Notification_Info);
+ mAppNameText.setTextAppearance(textAppearance);
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mAppNameText.getLayoutParams();
+ final int marginStart = mAppNameText.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_header_app_name_margin_start);
+ layoutParams.setMarginStart(marginStart);
+ }
+ if (mIconContainer != null) {
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mIconContainer.getLayoutParams();
+ layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+ layoutParams.setMarginStart(0);
+ }
+ if (mIcon != null) {
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams();
+ final int marginEnd = mIcon.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_header_icon_margin_end);
+ layoutParams.setMarginEnd(marginEnd);
+ }
+ }
+
/**
* Adds the remaining TransformTypes to the TransformHelper. This is done to make sure that each
* child is faded automatically and doesn't have to be manually added.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 351a3ef46dec..c9b1318feb13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -40,6 +40,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.HybridGroupManager;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import java.util.ArrayList;
@@ -99,6 +100,7 @@ public class NotificationChildrenContainer extends ViewGroup {
private boolean mIsLowPriority;
private OnClickListener mHeaderClickListener;
private ViewGroup mCurrentHeader;
+ private boolean mIsConversation;
private boolean mShowDividersWhenExpanded;
private boolean mHideDividersDuringExpand;
@@ -122,7 +124,7 @@ public class NotificationChildrenContainer extends ViewGroup {
public NotificationChildrenContainer(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mHybridGroupManager = new HybridGroupManager(getContext(), this);
+ mHybridGroupManager = new HybridGroupManager(getContext());
initDimens();
setClipChildren(false);
}
@@ -308,8 +310,9 @@ public class NotificationChildrenContainer extends ViewGroup {
return mAttachedChildren.size();
}
- public void recreateNotificationHeader(OnClickListener listener) {
+ public void recreateNotificationHeader(OnClickListener listener, boolean isConversation) {
mHeaderClickListener = listener;
+ mIsConversation = isConversation;
StatusBarNotification notification = mContainingNotification.getEntry().getSbn();
final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
notification.getNotification());
@@ -328,7 +331,16 @@ public class NotificationChildrenContainer extends ViewGroup {
header.reapply(getContext(), mNotificationHeader);
}
mNotificationHeaderWrapper.onContentUpdated(mContainingNotification);
- recreateLowPriorityHeader(builder);
+ if (mNotificationHeaderWrapper instanceof NotificationHeaderViewWrapper) {
+ NotificationHeaderViewWrapper headerWrapper =
+ (NotificationHeaderViewWrapper) mNotificationHeaderWrapper;
+ if (isConversation) {
+ headerWrapper.applyConversationSkin();
+ } else {
+ headerWrapper.clearConversationSkin();
+ }
+ }
+ recreateLowPriorityHeader(builder, isConversation);
updateHeaderVisibility(false /* animate */);
updateChildrenHeaderAppearance();
}
@@ -338,7 +350,7 @@ public class NotificationChildrenContainer extends ViewGroup {
*
* @param builder a builder to reuse. Otherwise the builder will be recovered.
*/
- private void recreateLowPriorityHeader(Notification.Builder builder) {
+ private void recreateLowPriorityHeader(Notification.Builder builder, boolean isConversation) {
RemoteViews header;
StatusBarNotification notification = mContainingNotification.getEntry().getSbn();
if (mIsLowPriority) {
@@ -362,6 +374,15 @@ public class NotificationChildrenContainer extends ViewGroup {
header.reapply(getContext(), mNotificationHeaderLowPriority);
}
mNotificationHeaderWrapperLowPriority.onContentUpdated(mContainingNotification);
+ if (mNotificationHeaderWrapper instanceof NotificationHeaderViewWrapper) {
+ NotificationHeaderViewWrapper headerWrapper =
+ (NotificationHeaderViewWrapper) mNotificationHeaderWrapper;
+ if (isConversation) {
+ headerWrapper.applyConversationSkin();
+ } else {
+ headerWrapper.clearConversationSkin();
+ }
+ }
resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, calculateDesiredHeader());
} else {
removeView(mNotificationHeaderLowPriority);
@@ -378,7 +399,7 @@ public class NotificationChildrenContainer extends ViewGroup {
int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* likeCollapsed */);
if (mUntruncatedChildCount > maxAllowedVisibleChildren) {
int number = mUntruncatedChildCount - maxAllowedVisibleChildren;
- mOverflowNumber = mHybridGroupManager.bindOverflowNumber(mOverflowNumber, number);
+ mOverflowNumber = mHybridGroupManager.bindOverflowNumber(mOverflowNumber, number, this);
if (mGroupOverFlowState == null) {
mGroupOverFlowState = new ViewState();
mNeverAppliedGroupState = true;
@@ -1141,7 +1162,7 @@ public class NotificationChildrenContainer extends ViewGroup {
removeView(mNotificationHeaderLowPriority);
mNotificationHeaderLowPriority = null;
}
- recreateNotificationHeader(listener);
+ recreateNotificationHeader(listener, mIsConversation);
initDimens();
for (int i = 0; i < mDividers.size(); i++) {
View prevDivider = mDividers.get(i);
@@ -1225,7 +1246,7 @@ public class NotificationChildrenContainer extends ViewGroup {
public void setIsLowPriority(boolean isLowPriority) {
mIsLowPriority = isLowPriority;
if (mContainingNotification != null) { /* we're not yet set up yet otherwise */
- recreateLowPriorityHeader(null /* existingBuilder */);
+ recreateLowPriorityHeader(null /* existingBuilder */, mIsConversation);
updateHeaderVisibility(false /* animate */);
}
if (mUserLocked) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index a19d35ac4e81..ec54b302b055 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -65,7 +65,6 @@ public class LockIcon extends KeyguardAffordanceView {
mPredrawRegistered = false;
int newState = mState;
- mOldState = mState;
Drawable icon = getIcon(newState);
setImageDrawable(icon, false);
@@ -135,6 +134,7 @@ public class LockIcon extends KeyguardAffordanceView {
}
void update(int newState, boolean pulsing, boolean dozing, boolean keyguardJustShown) {
+ mOldState = mState;
mState = newState;
mPulsing = pulsing;
mDozing = dozing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index a633e1979bad..a2e7306d4931 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -470,8 +470,10 @@ public class LockscreenLockIconController {
}
private int getState() {
- if ((mKeyguardStateController.canDismissLockScreen() || !mKeyguardShowing
- || mKeyguardStateController.isKeyguardGoingAway()) && !mSimLocked) {
+ if ((mKeyguardStateController.canDismissLockScreen()
+ || !mKeyguardStateController.isShowing()
+ || mKeyguardStateController.isKeyguardGoingAway()
+ || mKeyguardStateController.isKeyguardFadingAway()) && !mSimLocked) {
return STATE_LOCK_OPEN;
} else if (mTransientBiometricsError) {
return STATE_BIOMETRICS_ERROR;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 9ee204ea2e45..b2aa769f1bff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -98,6 +98,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.R;
+import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistHandleViewController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -185,6 +186,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private WindowManager mWindowManager;
private final CommandQueue mCommandQueue;
private long mLastLockToAppLongPress;
+ private final SystemActions mSystemActions;
private Locale mLocale;
private int mLayoutDirection;
@@ -373,6 +375,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
Optional<Recents> recentsOptional, Lazy<StatusBar> statusBarLazy,
ShadeController shadeController,
NotificationRemoteInputManager notificationRemoteInputManager,
+ SystemActions systemActions,
@Main Handler mainHandler) {
mAccessibilityManagerWrapper = accessibilityManagerWrapper;
mDeviceProvisionedController = deviceProvisionedController;
@@ -391,6 +394,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mCommandQueue = commandQueue;
mDivider = divider;
mRecentsOptional = recentsOptional;
+ mSystemActions = systemActions;
mHandler = mainHandler;
}
@@ -1168,6 +1172,16 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
.setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
.setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
.commitUpdate(mDisplayId);
+ registerAction(clickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON);
+ registerAction(longClickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER);
+ }
+
+ private void registerAction(boolean register, int actionId) {
+ if (register) {
+ mSystemActions.register(actionId);
+ } else {
+ mSystemActions.unregister(actionId);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
index 899aabb2e9a7..0b6e4b2ab598 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
@@ -201,6 +201,14 @@ public class SystemWindows {
attrs.flags |= FLAG_HARDWARE_ACCELERATED;
viewRoot.setView(view, attrs);
mViewRoots.put(view, viewRoot);
+
+ try {
+ mWmService.setShellRootAccessibilityWindow(mDisplayId, windowType,
+ viewRoot.getWindowToken());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error setting accessibility window for " + mDisplayId + ":"
+ + windowType, e);
+ }
}
SysUiWindowManager addRoot(int windowType) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index ff03fbae3f3a..317500cf5b02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -158,6 +158,13 @@ public class DozeSensorsTest extends SysuiTestCase {
verify(mTriggerSensor).setListening(eq(false));
}
+ @Test
+ public void testDestroy() {
+ mDozeSensors.destroy();
+
+ verify(mTriggerSensor).setListening(false);
+ }
+
private class TestableDozeSensors extends DozeSensors {
TestableDozeSensors() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index ffe3cd5bd504..2c4304d51720 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -83,8 +83,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
eq(false))).thenThrow(
RuntimeException.class);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap,
- smartActionsProvider, true, false);
+ ScreenshotSmartActions.getSmartActionsFuture(
+ "", Uri.parse("content://authority/data"), bitmap, smartActionsProvider,
+ true, false);
assertNotNull(smartActionsFuture);
List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
assertEquals(Collections.emptyList(), smartActions);
@@ -101,7 +102,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow(
RuntimeException.class);
List<Notification.Action> actions = ScreenshotSmartActions.getSmartActions(
- "", "", smartActionsFuture, timeoutMs, mSmartActionsProvider);
+ "", smartActionsFuture, timeoutMs, mSmartActionsProvider);
assertEquals(Collections.emptyList(), actions);
}
@@ -122,8 +123,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
Bitmap bitmap = mock(Bitmap.class);
when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap,
- mSmartActionsProvider, true, true);
+ ScreenshotSmartActions.getSmartActionsFuture(
+ "", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider,
+ true, true);
verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(),
eq(false));
assertNotNull(smartActionsFuture);
@@ -136,8 +138,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
public void testScreenshotNotificationSmartActionsProviderInvokedOnce() {
Bitmap bitmap = mock(Bitmap.class);
when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
- ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap, mSmartActionsProvider,
- true, true);
+ ScreenshotSmartActions.getSmartActionsFuture(
+ "", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider, true,
+ true);
verify(mSmartActionsProvider, times(1))
.getActions(any(), any(), any(), any(), eq(true));
}
@@ -152,7 +155,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider(
mContext, null, mHandler);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap,
+ ScreenshotSmartActions.getSmartActionsFuture("", null, bitmap,
actionsProvider,
true, true);
assertNotNull(smartActionsFuture);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index c6d57e6df028..d124bad438c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -20,6 +20,8 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.content.Intent.ACTION_USER_SWITCHED;
import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE;
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
import static junit.framework.Assert.assertFalse;
@@ -42,6 +44,7 @@ import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
@@ -99,6 +102,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
private UserInfo mSecondaryUser;
private UserInfo mWorkUser;
private TestNotificationLockscreenUserManager mLockscreenUserManager;
+ private NotificationEntry mCurrentUserNotif;
+ private NotificationEntry mSecondaryUserNotif;
+ private NotificationEntry mWorkProfileNotif;
@Before
public void setUp() {
@@ -116,6 +122,21 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
Handler.createAsync(Looper.myLooper()));
+ Notification notifWithPrivateVisibility = new Notification();
+ notifWithPrivateVisibility.visibility = Notification.VISIBILITY_PRIVATE;
+ mCurrentUserNotif = new NotificationEntryBuilder()
+ .setNotification(notifWithPrivateVisibility)
+ .setUser(new UserHandle(mCurrentUser.id))
+ .build();
+ mSecondaryUserNotif = new NotificationEntryBuilder()
+ .setNotification(notifWithPrivateVisibility)
+ .setUser(new UserHandle(mSecondaryUser.id))
+ .build();
+ mWorkProfileNotif = new NotificationEntryBuilder()
+ .setNotification(notifWithPrivateVisibility)
+ .setUser(new UserHandle(mWorkUser.id))
+ .build();
+
mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext);
mLockscreenUserManager.setUpWithPresenter(mPresenter);
}
@@ -155,7 +176,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id);
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
- assertFalse(mLockscreenUserManager.userAllowsNotificationsInPublic(mCurrentUser.id));
+ assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id));
}
@Test
@@ -163,7 +184,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id);
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
- assertFalse(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic());
+ assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id));
}
@Test
@@ -171,7 +192,107 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id);
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
- assertTrue(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic());
+ assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id));
+ }
+
+ @Test
+ public void testCurrentUserPrivateNotificationsNotRedacted() {
+ // GIVEN current user doesn't allow private notifications to show
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN current user's notification is redacted
+ assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
+ }
+
+ @Test
+ public void testCurrentUserPrivateNotificationsRedacted() {
+ // GIVEN current user allows private notifications to show
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN current user's notification isn't redacted
+ assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
+ }
+
+ @Test
+ public void testWorkPrivateNotificationsRedacted() {
+ // GIVEN work profile doesn't private notifications to show
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN work profile notification is redacted
+ assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
+ }
+
+ @Test
+ public void testWorkPrivateNotificationsNotRedacted() {
+ // GIVEN work profile allows private notifications to show
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN work profile notification isn't redacted
+ assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
+ }
+
+ @Test
+ public void testWorkPrivateNotificationsNotRedacted_otherUsersRedacted() {
+ // GIVEN work profile allows private notifications to show but the other users don't
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0,
+ mSecondaryUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN the work profile notification doesn't need to be redacted
+ assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
+
+ // THEN the current user and secondary user notifications do need to be redacted
+ assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
+ assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
+ }
+
+ @Test
+ public void testWorkProfileRedacted_otherUsersNotRedacted() {
+ // GIVEN work profile doesn't allow private notifications to show but the other users do
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1,
+ mSecondaryUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN the work profile notification needs to be redacted
+ assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
+
+ // THEN the current user and secondary user notifications don't need to be redacted
+ assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
+ assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
+ }
+
+ @Test
+ public void testSecondaryUserNotRedacted_currentUserRedacted() {
+ // GIVEN secondary profile allows private notifications to show but the current user
+ // doesn't allow private notifications to show
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1,
+ mSecondaryUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+
+ // THEN the secondary profile notification still needs to be redacted because the current
+ // user's setting takes precedence
+ assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
}
@Test
@@ -233,6 +354,45 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(entry));
}
+ @Test
+ public void testShowSilentNotificationsPeopleBucket_settingSaysHide() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0);
+
+ final Notification notification = mock(Notification.class);
+ when(notification.isForegroundService()).thenReturn(true);
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_LOW)
+ .setNotification(notification)
+ .build();
+ entry.setBucket(BUCKET_PEOPLE);
+ assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(entry));
+ }
+
+ @Test
+ public void testShowSilentNotificationsMediaBucket_settingSaysHide() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0);
+
+ final Notification notification = mock(Notification.class);
+ when(notification.isForegroundService()).thenReturn(true);
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_LOW)
+ .setNotification(notification)
+ .build();
+ entry.setBucket(BUCKET_MEDIA_CONTROLS);
+ // always show media controls, even if they're silent
+ assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(entry));
+ }
+
private class TestNotificationLockscreenUserManager
extends NotificationLockscreenUserManagerImpl {
public TestNotificationLockscreenUserManager(Context context) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
index a2599ecb50da..b4cabfd1855d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
@@ -32,6 +32,7 @@ import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
@@ -228,6 +229,56 @@ class NotificationRankingManagerTest : SysuiTestCase() {
whenever(personNotificationIdentifier.getPeopleNotificationType(b.sbn, b.ranking))
.thenReturn(TYPE_IMPORTANT_PERSON)
+ whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_IMPORTANT_PERSON))
+ .thenReturn(TYPE_IMPORTANT_PERSON.compareTo(TYPE_PERSON))
+ whenever(personNotificationIdentifier.compareTo(TYPE_IMPORTANT_PERSON, TYPE_PERSON))
+ .thenReturn(TYPE_PERSON.compareTo(TYPE_IMPORTANT_PERSON))
+
+ assertEquals(
+ listOf(b, a),
+ rankingManager.updateRanking(null, listOf(a, b), "test"))
+ }
+
+ @Test
+ fun testSort_fullPeople() {
+ whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
+ val aN = Notification.Builder(mContext, "test")
+ .setStyle(Notification.MessagingStyle(""))
+ .build()
+ val a = NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_HIGH)
+ .setPkg("pkg")
+ .setOpPkg("pkg")
+ .setTag("tag")
+ .setNotification(aN)
+ .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
+ .setUser(mContext.user)
+ .setOverrideGroupKey("")
+ .build()
+ whenever(personNotificationIdentifier.getPeopleNotificationType(a.sbn, a.ranking))
+ .thenReturn(TYPE_PERSON)
+
+ val bN = Notification.Builder(mContext, "test")
+ .setStyle(Notification.MessagingStyle(""))
+ .build()
+ val b = NotificationEntryBuilder()
+ .setImportance(IMPORTANCE_HIGH)
+ .setPkg("pkg2")
+ .setOpPkg("pkg2")
+ .setTag("tag")
+ .setNotification(bN)
+ .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
+ .setUser(mContext.user)
+ .setOverrideGroupKey("")
+ .build()
+ whenever(personNotificationIdentifier.getPeopleNotificationType(b.sbn, b.ranking))
+ .thenReturn(TYPE_FULL_PERSON)
+
+ whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_FULL_PERSON))
+ .thenReturn(TYPE_FULL_PERSON.compareTo(TYPE_PERSON))
+ whenever(personNotificationIdentifier.compareTo(TYPE_FULL_PERSON, TYPE_PERSON))
+ .thenReturn(TYPE_PERSON.compareTo(TYPE_FULL_PERSON))
+
assertEquals(
listOf(b, a),
rankingManager.updateRanking(null, listOf(a, b), "test"))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index 703789151895..b9055ec0bb7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -146,7 +146,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
@Test
public void testRecreateNotificationHeader_hasHeader() {
- mChildrenContainer.recreateNotificationHeader(null);
+ mChildrenContainer.recreateNotificationHeader(null, false);
Assert.assertNotNull("Children container must have a header after recreation",
mChildrenContainer.getCurrentHeaderView());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 9aa0fdd2a6f7..a77f8c649f30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -62,6 +62,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.SysuiTestableContext;
+import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.model.SysUiState;
@@ -102,6 +103,8 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
private Divider mDivider;
@Mock
private Recents mRecents;
+ @Mock
+ private SystemActions mSystemActions;
private AccessibilityManagerWrapper mAccessibilityWrapper =
new AccessibilityManagerWrapper(mContext) {
@@ -257,6 +260,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
() -> mock(StatusBar.class),
mock(ShadeController.class),
mock(NotificationRemoteInputManager.class),
+ mock(SystemActions.class),
mHandler);
}
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
index 2a7330098faf..12d6c2cfbaeb 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
index ea04821e33bd..f4b15aab19b7 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
index 617c50dd0ce8..0a0aa217c381 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
index 0e437593ee87..2ea2467e5879 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 55344fc75d65..c4a1078d0be0 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -41,6 +41,7 @@ import java.io.IOException;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
+import java.util.NoSuchElementException;
/**
@@ -143,7 +144,7 @@ public class OffloadHardwareInterface {
IOffloadConfig offloadConfig;
try {
offloadConfig = IOffloadConfig.getService(true /*retry*/);
- } catch (RemoteException e) {
+ } catch (RemoteException | NoSuchElementException e) {
mLog.e("getIOffloadConfig error " + e);
return false;
}
@@ -239,8 +240,8 @@ public class OffloadHardwareInterface {
if (mOffloadControl == null) {
try {
- mOffloadControl = IOffloadControl.getService();
- } catch (RemoteException e) {
+ mOffloadControl = IOffloadControl.getService(true /*retry*/);
+ } catch (RemoteException | NoSuchElementException e) {
mLog.e("tethering offload control not supported: " + e);
return false;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index a1fc3fa1857d..35054991d3ff 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -85,7 +85,6 @@ public class SystemActionPerformer {
private final AccessibilityAction mLegacyNotificationsAction;
private final AccessibilityAction mLegacyQuickSettingsAction;
private final AccessibilityAction mLegacyPowerDialogAction;
- private final AccessibilityAction mLegacyToggleSplitScreenAction;
private final AccessibilityAction mLegacyLockScreenAction;
private final AccessibilityAction mLegacyTakeScreenshotAction;
@@ -142,10 +141,6 @@ public class SystemActionPerformer {
AccessibilityService.GLOBAL_ACTION_POWER_DIALOG,
mContext.getResources().getString(
R.string.accessibility_system_action_power_dialog_label));
- mLegacyToggleSplitScreenAction = new AccessibilityAction(
- AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN,
- mContext.getResources().getString(
- R.string.accessibility_system_action_toggle_split_screen_label));
mLegacyLockScreenAction = new AccessibilityAction(
AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN,
mContext.getResources().getString(
@@ -235,10 +230,6 @@ public class SystemActionPerformer {
systemActions.add(mLegacyPowerDialogAction);
}
if (!mRegisteredSystemActions.containsKey(
- AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)) {
- systemActions.add(mLegacyToggleSplitScreenAction);
- }
- if (!mRegisteredSystemActions.containsKey(
AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN)) {
systemActions.add(mLegacyLockScreenAction);
}
diff --git a/services/art-profile b/services/art-profile
index e2974a1b7ae3..559356bdd1f5 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -32290,7 +32290,6 @@ HPLcom/android/server/pm/permission/BasePermission;->generatePermissionInfo(Ljav
HSPLcom/android/server/pm/permission/BasePermission;->getName()Ljava/lang/String;
HSPLcom/android/server/pm/permission/BasePermission;->getProtectionLevel()I
HSPLcom/android/server/pm/permission/BasePermission;->getSourcePackageName()Ljava/lang/String;
-HSPLcom/android/server/pm/permission/BasePermission;->getSourcePackageSetting()Lcom/android/server/pm/PackageSettingBase;
PLcom/android/server/pm/permission/BasePermission;->getUid()I
HSPLcom/android/server/pm/permission/BasePermission;->isAppOp()Z
HSPLcom/android/server/pm/permission/BasePermission;->isAppPredictor()Z
@@ -32329,7 +32328,6 @@ HSPLcom/android/server/pm/permission/BasePermission;->readLPw(Ljava/util/Map;Lor
HSPLcom/android/server/pm/permission/BasePermission;->setGids([IZ)V
HSPLcom/android/server/pm/permission/BasePermission;->setPermission(Landroid/content/pm/parsing/ComponentParseUtils$ParsedPermission;)V
PLcom/android/server/pm/permission/BasePermission;->setPermission(Landroid/content/pm/parsing/component/ParsedPermission;)V
-HSPLcom/android/server/pm/permission/BasePermission;->setSourcePackageSetting(Lcom/android/server/pm/PackageSettingBase;)V
HSPLcom/android/server/pm/permission/BasePermission;->updateDynamicPermission(Ljava/util/Collection;)V
HSPLcom/android/server/pm/permission/BasePermission;->writeLPr(Lorg/xmlpull/v1/XmlSerializer;)V
HSPLcom/android/server/pm/permission/DefaultPermissionGrantPolicy$1;-><init>(Lcom/android/server/pm/permission/DefaultPermissionGrantPolicy;Landroid/os/Looper;)V
diff --git a/services/art-profile-boot b/services/art-profile-boot
index fe4178ac4a50..addc906fc86b 100644
--- a/services/art-profile-boot
+++ b/services/art-profile-boot
@@ -171,7 +171,6 @@ Lcom/android/server/pm/PackageUsage;->readToken(Ljava/io/InputStream;Ljava/lang/
Lcom/android/server/pm/PackageUsage;->readVersion1LP(Ljava/util/Map;Ljava/io/InputStream;Ljava/lang/StringBuffer;)V
Lcom/android/server/pm/PackageUsage;->parseAsLong(Ljava/lang/String;)J
Lcom/android/server/pm/CompilerStats;->read(Ljava/io/Reader;)Z
-Lcom/android/server/pm/permission/BasePermission;->getSourcePackageSetting()Lcom/android/server/pm/PackageSettingBase;
Lcom/android/server/pm/permission/PermissionManagerService;->updatePermissionSourcePackage(Ljava/lang/String;Landroid/content/pm/PackageParser$Package;)Z
Lcom/android/server/pm/permission/BasePermission;->isDynamic()Z
Lcom/android/server/pm/permission/PermissionManagerService;->cacheBackgroundToForegoundPermissionMapping()V
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 992e98473ae7..dc35c774f71e 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -318,6 +318,9 @@ public class UserBackupManagerService {
private static final String SERIAL_ID_FILE = "serial_id";
+ private static final String SKIP_USER_FACING_DATA = "backup_skip_user_facing_data";
+ private static final String WALLPAPER_PACKAGE = "com.android.wallpaperbackup";
+
private final @UserIdInt int mUserId;
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private final TransportManager mTransportManager;
@@ -3553,6 +3556,40 @@ public class UserBackupManagerService {
}
}
+ /**
+ * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_data' is
+ * set to true in secure settings. See b/153940088 for details.
+ *
+ * TODO(b/154822946): Remove this logic in the next release.
+ */
+ public List<PackageInfo> filterUserFacingPackages(List<PackageInfo> packages) {
+ if (!shouldSkipUserFacingData()) {
+ return packages;
+ }
+
+ List<PackageInfo> filteredPackages = new ArrayList<>(packages.size());
+ for (PackageInfo packageInfo : packages) {
+ if (!shouldSkipPackage(packageInfo.packageName)) {
+ filteredPackages.add(packageInfo);
+ } else {
+ Slog.i(TAG, "Will skip backup/restore for " + packageInfo.packageName);
+ }
+ }
+
+ return filteredPackages;
+ }
+
+ @VisibleForTesting
+ public boolean shouldSkipUserFacingData() {
+ return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_DATA,
+ /* def */ 0) != 0;
+ }
+
+ @VisibleForTesting
+ public boolean shouldSkipPackage(String packageName) {
+ return WALLPAPER_PACKAGE.equals(packageName);
+ }
+
private void updateStateForTransport(String newTransportName) {
// Publish the name change
Settings.Secure.putStringForUser(mContext.getContentResolver(),
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index f7f01387cf78..738dd9bf0f0d 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -61,6 +61,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -131,7 +132,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
private UserBackupManagerService mUserBackupManagerService;
private final Object mCancelLock = new Object();
- ArrayList<PackageInfo> mPackages;
+ List<PackageInfo> mPackages;
PackageInfo mCurrentPackage;
boolean mUpdateSchedule;
CountDownLatch mLatch;
@@ -249,6 +250,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
null);
}
}
+
+ mPackages = backupManagerService.filterUserFacingPackages(mPackages);
}
private void registerTask() {
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index e434be648dcb..12113fea12a4 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -270,6 +270,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
}
}
+ mAcceptSet = backupManagerService.filterUserFacingPackages(mAcceptSet);
+
if (MORE_DEBUG) {
Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size());
for (PackageInfo info : mAcceptSet) {
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index b6bbe1912a16..b09b2605a791 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -51,7 +51,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub {
mContext = context;
}
- private IGsiService getGsiService() throws RemoteException {
+ private IGsiService getGsiService() {
checkPermission();
if (mGsiService != null) {
return mGsiService;
@@ -60,8 +60,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub {
}
private void checkPermission() {
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires MANAGE_DYNAMIC_SYSTEM permission");
}
@@ -147,12 +146,12 @@ public class DynamicSystemService extends IDynamicSystemService.Stub {
}
@Override
- public boolean isInUse() throws RemoteException {
+ public boolean isInUse() {
return SystemProperties.getBoolean("ro.gsid.image_running", false);
}
@Override
- public boolean isInstalled() throws RemoteException {
+ public boolean isInstalled() {
boolean installed = SystemProperties.getBoolean("gsid.image_installed", false);
Slog.i(TAG, "isInstalled(): " + installed);
return installed;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index ee4697f37f52..de9b02ffd636 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -4133,9 +4133,6 @@ public class AppOpsService extends IAppOpsService.Stub {
throws NumberFormatException,
XmlPullParserException, IOException {
int opCode = Integer.parseInt(parser.getAttributeValue(null, "n"));
- if (isIgnoredAppOp(opCode)) {
- return;
- }
Op op = new Op(uidState, pkgName, opCode, uidState.uid);
final int mode = XmlUtils.readIntAttribute(parser, "m",
@@ -4170,16 +4167,6 @@ public class AppOpsService extends IAppOpsService.Stub {
ops.put(op.op, op);
}
- //TODO(b/149995538): Remove once this has reached all affected devices
- private static boolean isIgnoredAppOp(int op) {
- switch (op) {
- case AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE:
- return true;
- default:
- return false;
- }
- }
-
void writeState() {
synchronized (mFile) {
FileOutputStream stream;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index a358707a4346..3ff6ec1afa41 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -32,6 +32,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.Constants.LocalActivePort;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
@@ -144,7 +145,8 @@ abstract class HdmiCecLocalDevice {
// A collection of FeatureAction.
// Note that access to this collection should happen in service thread.
- private final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>();
+ @VisibleForTesting
+ final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>();
private final Handler mHandler =
new Handler() {
@@ -544,6 +546,8 @@ abstract class HdmiCecLocalDevice {
} else if (mService.isPowerStandbyOrTransient() && isPowerOnOrToggleCommand(message)) {
mService.wakeUp();
return true;
+ } else if (!mService.isHdmiCecVolumeControlEnabled() && isVolumeOrMuteCommand(message)) {
+ return false;
}
final long downTime = SystemClock.uptimeMillis();
@@ -618,6 +622,16 @@ abstract class HdmiCecLocalDevice {
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION);
}
+ static boolean isVolumeOrMuteCommand(HdmiCecMessage message) {
+ byte[] params = message.getParams();
+ return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED
+ && (params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN
+ || params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP
+ || params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE
+ || params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION
+ || params[0] == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
+ }
+
protected boolean handleTextViewOn(HdmiCecMessage message) {
return false;
}
@@ -1038,6 +1052,9 @@ abstract class HdmiCecLocalDevice {
@ServiceThreadOnly
protected void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
assertRunOnServiceThread();
+ if (!mService.isHdmiCecVolumeControlEnabled()) {
+ return;
+ }
if (!HdmiCecKeycode.isVolumeKeycode(keyCode)) {
Slog.w(TAG, "Not a volume key: " + keyCode);
return;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index e5a08d3e79aa..611b8c69077d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -575,7 +575,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
@ServiceThreadOnly
protected boolean handleGiveAudioStatus(HdmiCecMessage message) {
assertRunOnServiceThread();
- if (isSystemAudioControlFeatureEnabled()) {
+ if (isSystemAudioControlFeatureEnabled() && mService.isHdmiCecVolumeControlEnabled()) {
reportAudioStatus(message.getSource());
} else {
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
@@ -930,6 +930,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
void reportAudioStatus(int source) {
assertRunOnServiceThread();
+ if (!mService.isHdmiCecVolumeControlEnabled()) {
+ return;
+ }
int volume = mService.getAudioManager().getStreamVolume(AudioManager.STREAM_MUSIC);
boolean mute = mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a702ce517f40..0ac4f9ee4c6d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -678,6 +678,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@ServiceThreadOnly
protected boolean handleReportAudioStatus(HdmiCecMessage message) {
assertRunOnServiceThread();
+ if (!mService.isHdmiCecVolumeControlEnabled()) {
+ return false;
+ }
boolean mute = HdmiUtils.isAudioStatusMute(message);
int volume = HdmiUtils.getAudioStatusVolume(message);
@@ -987,7 +990,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
void setAudioStatus(boolean mute, int volume) {
- if (!isSystemAudioActivated()) {
+ if (!isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) {
return;
}
synchronized (mLock) {
@@ -1009,7 +1012,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
// On initialization process, getAvrDeviceInfo() may return null and cause exception
return;
}
- if (delta == 0 || !isSystemAudioActivated()) {
+ if (delta == 0 || !isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) {
return;
}
@@ -1038,7 +1041,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@ServiceThreadOnly
void changeMute(boolean mute) {
assertRunOnServiceThread();
- if (getAvrDeviceInfo() == null) {
+ if (getAvrDeviceInfo() == null || !mService.isHdmiCecVolumeControlEnabled()) {
// On initialization process, getAvrDeviceInfo() may return null and cause exception
return;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index d9e30250ba2d..53f9ebcbd8dd 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -177,6 +177,10 @@ public class HdmiControlService extends SystemService {
@GuardedBy("mLock")
protected final ActiveSource mActiveSource = new ActiveSource();
+ // Whether HDMI CEC volume control is enabled or not.
+ @GuardedBy("mLock")
+ private boolean mHdmiCecVolumeControlEnabled;
+
// Whether System Audio Mode is activated or not.
@GuardedBy("mLock")
private boolean mSystemAudioActivated = false;
@@ -497,6 +501,8 @@ public class HdmiControlService extends SystemService {
mPowerStatus = getInitialPowerStatus();
mProhibitMode = false;
mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true);
+ mHdmiCecVolumeControlEnabled = readBooleanSetting(
+ Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true);
mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true);
if (mCecController == null) {
@@ -646,6 +652,7 @@ public class HdmiControlService extends SystemService {
ContentResolver resolver = getContext().getContentResolver();
String[] settings = new String[] {
Global.HDMI_CONTROL_ENABLED,
+ Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
@@ -674,6 +681,9 @@ public class HdmiControlService extends SystemService {
case Global.HDMI_CONTROL_ENABLED:
setControlEnabled(enabled);
break;
+ case Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED:
+ setHdmiCecVolumeControlEnabled(enabled);
+ break;
case Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED:
if (isTvDeviceEnabled()) {
tv().setAutoWakeup(enabled);
@@ -1273,7 +1283,9 @@ public class HdmiControlService extends SystemService {
}
void setAudioStatus(boolean mute, int volume) {
- if (!isTvDeviceEnabled() || !tv().isSystemAudioActivated()) {
+ if (!isTvDeviceEnabled()
+ || !tv().isSystemAudioActivated()
+ || !isHdmiCecVolumeControlEnabled()) {
return;
}
AudioManager audioManager = getAudioManager();
@@ -2187,6 +2199,24 @@ public class HdmiControlService extends SystemService {
}
@Override
+ public boolean isHdmiCecVolumeControlEnabled() {
+ enforceAccessPermission();
+ return HdmiControlService.this.isHdmiCecVolumeControlEnabled();
+ }
+
+ @Override
+ public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) {
+ enforceAccessPermission();
+ runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ HdmiControlService.this.setHdmiCecVolumeControlEnabled(
+ isHdmiCecVolumeControlEnabled);
+ }
+ });
+ }
+
+ @Override
public void reportAudioStatus(final int deviceType, final int volume, final int maxVolume,
final boolean isMute) {
enforceAccessPermission();
@@ -2250,6 +2280,7 @@ public class HdmiControlService extends SystemService {
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
pw.println("mMhlInputChangeEnabled: " + mMhlInputChangeEnabled);
pw.println("mSystemAudioActivated: " + isSystemAudioActivated());
+ pw.println("mHdmiCecVolumeControlEnabled " + mHdmiCecVolumeControlEnabled);
pw.decreaseIndent();
pw.println("mMhlController: ");
@@ -2982,6 +3013,29 @@ public class HdmiControlService extends SystemService {
}
}
+ void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
+ assertRunOnServiceThread();
+ synchronized (mLock) {
+ mHdmiCecVolumeControlEnabled = isHdmiCecVolumeControlEnabled;
+
+ boolean storedValue = readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
+ true);
+ if (storedValue != isHdmiCecVolumeControlEnabled) {
+ HdmiLogger.debug("Changing HDMI CEC volume control feature state: %s",
+ isHdmiCecVolumeControlEnabled);
+ writeBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
+ isHdmiCecVolumeControlEnabled);
+ }
+ }
+ }
+
+ boolean isHdmiCecVolumeControlEnabled() {
+ assertRunOnServiceThread();
+ synchronized (mLock) {
+ return mHdmiCecVolumeControlEnabled;
+ }
+ }
+
boolean isProhibitMode() {
synchronized (mLock) {
return mProhibitMode;
@@ -3022,8 +3076,12 @@ public class HdmiControlService extends SystemService {
if (enabled) {
enableHdmiControlService();
+ setHdmiCecVolumeControlEnabled(
+ readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true));
return;
}
+
+ setHdmiCecVolumeControlEnabled(false);
// Call the vendor handler before the service is disabled.
invokeVendorCommandListenersOnControlStateChanged(false,
HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e6129b9b1f32..115899a2a518 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1069,7 +1069,7 @@ public class InputManagerService extends IInputManager.Stub
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
- intent, 0, null, UserHandle.CURRENT);
+ intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
Resources r = mContext.getResources();
Notification notification =
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 393e8db96c01..2cae1d64ca34 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -360,7 +360,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
* Verify the UID and return the installer package name.
*
* @return the package name of the installer, or null if it cannot be determined or it is
- * installed via adb.
+ * installed via adb.
*/
@Nullable
private String getInstallerPackageName(Intent intent) {
@@ -568,7 +568,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
try (PackageParser2 parser = mParserSupplier.get()) {
ParsedPackage pkg = parser.parsePackage(installationPath, 0, false);
int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA;
- pkg.setSigningDetails(ParsingPackageUtils.collectCertificates(pkg, false));
+ // APK signatures is already verified elsewhere in PackageManager. We do not need to
+ // verify it again since it could cause a timeout for large APKs.
+ pkg.setSigningDetails(
+ ParsingPackageUtils.collectCertificates(pkg, /* skipVerify= */ true));
return PackageInfoUtils.generate(
pkg,
null,
@@ -709,7 +712,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
// Filter out the rule provider packages that are not system apps.
List<String> systemAppRuleProviders = new ArrayList<>();
- for (String ruleProvider: integrityRuleProviders) {
+ for (String ruleProvider : integrityRuleProviders) {
if (isSystemApp(ruleProvider)) {
systemAppRuleProviders.add(ruleProvider);
}
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 0b9697840a1f..3a29622556cc 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -33,29 +33,28 @@ import java.util.Map;
/**
* Provides a way to customize behavior for media key events.
* <p>
- * In order to override the implementation of the single/double/triple click or long press,
+ * In order to override the implementation of the single/double/triple tap or long press,
* {@link #setOverriddenKeyEvents(int, int)} should be called for each key code with the
* overridden {@link KeyEventType} bit value set, and the corresponding method,
- * {@link #onSingleClick(KeyEvent)}, {@link #onDoubleClick(KeyEvent)},
- * {@link #onTripleClick(KeyEvent)}, {@link #onLongPress(KeyEvent)} should be implemented.
+ * {@link #onSingleTap(KeyEvent)}, {@link #onDoubleTap(KeyEvent)},
+ * {@link #onTripleTap(KeyEvent)}, {@link #onLongPress(KeyEvent)} should be implemented.
* <p>
* Note: When instantiating this class, {@link MediaSessionService} will only use the constructor
* without any parameters.
*/
-// TODO: Change API names from using "click" to "tap"
// TODO: Move this class to apex/media/
public abstract class MediaKeyDispatcher {
@IntDef(flag = true, value = {
- KEY_EVENT_SINGLE_CLICK,
- KEY_EVENT_DOUBLE_CLICK,
- KEY_EVENT_TRIPLE_CLICK,
+ KEY_EVENT_SINGLE_TAP,
+ KEY_EVENT_DOUBLE_TAP,
+ KEY_EVENT_TRIPLE_TAP,
KEY_EVENT_LONG_PRESS
})
@Retention(RetentionPolicy.SOURCE)
@interface KeyEventType {}
- static final int KEY_EVENT_SINGLE_CLICK = 1 << 0;
- static final int KEY_EVENT_DOUBLE_CLICK = 1 << 1;
- static final int KEY_EVENT_TRIPLE_CLICK = 1 << 2;
+ static final int KEY_EVENT_SINGLE_TAP = 1 << 0;
+ static final int KEY_EVENT_DOUBLE_TAP = 1 << 1;
+ static final int KEY_EVENT_TRIPLE_TAP = 1 << 2;
static final int KEY_EVENT_LONG_PRESS = 1 << 3;
private Map<Integer, Integer> mOverriddenKeyEvents;
@@ -110,16 +109,16 @@ public abstract class MediaKeyDispatcher {
return mOverriddenKeyEvents;
}
- static boolean isSingleClickOverridden(@KeyEventType int overriddenKeyEvents) {
- return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_SINGLE_CLICK) != 0;
+ static boolean isSingleTapOverridden(@KeyEventType int overriddenKeyEvents) {
+ return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_SINGLE_TAP) != 0;
}
- static boolean isDoubleClickOverridden(@KeyEventType int overriddenKeyEvents) {
- return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_DOUBLE_CLICK) != 0;
+ static boolean isDoubleTapOverridden(@KeyEventType int overriddenKeyEvents) {
+ return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_DOUBLE_TAP) != 0;
}
- static boolean isTripleClickOverridden(@KeyEventType int overriddenKeyEvents) {
- return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_TRIPLE_CLICK) != 0;
+ static boolean isTripleTapOverridden(@KeyEventType int overriddenKeyEvents) {
+ return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_TRIPLE_TAP) != 0;
}
static boolean isLongPressOverridden(@KeyEventType int overriddenKeyEvents) {
@@ -150,11 +149,11 @@ public abstract class MediaKeyDispatcher {
}
/**
- * Customized implementation for single click event. Will be run if
- * {@link #KEY_EVENT_SINGLE_CLICK} flag is on for the corresponding key code from
+ * Customized implementation for single tap event. Will be run if
+ * {@link #KEY_EVENT_SINGLE_TAP} flag is on for the corresponding key code from
* {@link #getOverriddenKeyEvents()}.
*
- * It is considered a single click if only one {@link KeyEvent} with the same
+ * It is considered a single tap if only one {@link KeyEvent} with the same
* {@link KeyEvent#getKeyCode()} is dispatched within
* {@link ViewConfiguration#getMultiPressTimeout()} milliseconds. Change the
* {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
@@ -163,15 +162,15 @@ public abstract class MediaKeyDispatcher {
*
* @param keyEvent
*/
- void onSingleClick(KeyEvent keyEvent) {
+ void onSingleTap(KeyEvent keyEvent) {
}
/**
- * Customized implementation for double click event. Will be run if
- * {@link #KEY_EVENT_DOUBLE_CLICK} flag is on for the corresponding key code from
+ * Customized implementation for double tap event. Will be run if
+ * {@link #KEY_EVENT_DOUBLE_TAP} flag is on for the corresponding key code from
* {@link #getOverriddenKeyEvents()}.
*
- * It is considered a double click if two {@link KeyEvent}s with the same
+ * It is considered a double tap if two {@link KeyEvent}s with the same
* {@link KeyEvent#getKeyCode()} are dispatched within
* {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the
* {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
@@ -180,15 +179,15 @@ public abstract class MediaKeyDispatcher {
*
* @param keyEvent
*/
- void onDoubleClick(KeyEvent keyEvent) {
+ void onDoubleTap(KeyEvent keyEvent) {
}
/**
- * Customized implementation for triple click event. Will be run if
- * {@link #KEY_EVENT_TRIPLE_CLICK} flag is on for the corresponding key code from
+ * Customized implementation for triple tap event. Will be run if
+ * {@link #KEY_EVENT_TRIPLE_TAP} flag is on for the corresponding key code from
* {@link #getOverriddenKeyEvents()}.
*
- * It is considered a triple click if three {@link KeyEvent}s with the same
+ * It is considered a triple tap if three {@link KeyEvent}s with the same
* {@link KeyEvent#getKeyCode()} are dispatched within
* {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the
* {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval.
@@ -197,7 +196,7 @@ public abstract class MediaKeyDispatcher {
*
* @param keyEvent
*/
- void onTripleClick(KeyEvent keyEvent) {
+ void onTripleTap(KeyEvent keyEvent) {
}
/**
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 476c9f879ca2..bc0e8166fb42 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -18,6 +18,12 @@ package com.android.server.media;
import static android.os.UserHandle.USER_ALL;
+import static com.android.server.media.MediaKeyDispatcher.KEY_EVENT_LONG_PRESS;
+import static com.android.server.media.MediaKeyDispatcher.isDoubleTapOverridden;
+import static com.android.server.media.MediaKeyDispatcher.isLongPressOverridden;
+import static com.android.server.media.MediaKeyDispatcher.isSingleTapOverridden;
+import static com.android.server.media.MediaKeyDispatcher.isTripleTapOverridden;
+
import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.KeyguardManager;
@@ -105,7 +111,7 @@ public class MediaSessionService extends SystemService implements Monitor {
private static final int SESSION_CREATION_LIMIT_PER_UID = 100;
private static final int LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout()
+ /* Buffer for delayed delivery of key event */ 50;
- private static final int MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout();
+ private static final int MULTI_TAP_TIMEOUT = ViewConfiguration.getMultiPressTimeout();
private final Context mContext;
private final SessionManagerImpl mSessionManagerImpl;
@@ -1101,9 +1107,12 @@ public class MediaSessionService extends SystemService implements Monitor {
"android.media.AudioService.WAKELOCK_ACQUIRED";
private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; // magic number
- private KeyEvent mPendingFirstDownKeyEvent = null;
+ private KeyEvent mTrackingFirstDownKeyEvent = null;
private boolean mIsLongPressing = false;
private Runnable mLongPressTimeoutRunnable = null;
+ private int mMultiTapCount = 0;
+ private int mMultiTapKeyCode = 0;
+ private Runnable mMultiTapTimeoutRunnable = null;
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
@@ -2117,10 +2126,12 @@ public class MediaSessionService extends SystemService implements Monitor {
}
// A long press is determined by:
- // 1) A KeyEvent with KeyEvent.ACTION_DOWN and repeat count of 0, followed by
- // 2) A KeyEvent with KeyEvent.ACTION_DOWN and repeat count of 1 and FLAG_LONG_PRESS within
- // ViewConfiguration.getLongPressTimeout().
- // TODO: Add description about what a click is determined by.
+ // 1) A KeyEvent.ACTION_DOWN KeyEvent and repeat count of 0, followed by
+ // 2) A KeyEvent.ACTION_DOWN KeyEvent with the same key code, a repeat count of 1, and
+ // FLAG_LONG_PRESS received within ViewConfiguration.getLongPressTimeout().
+ // A tap is determined by:
+ // 1) A KeyEvent.ACTION_DOWN KeyEvent followed by
+ // 2) A KeyEvent.ACTION_UP KeyEvent with the same key code.
private void handleKeyEventLocked(String packageName, int pid, int uid,
boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
if (keyEvent.isCanceled()) {
@@ -2129,61 +2140,121 @@ public class MediaSessionService extends SystemService implements Monitor {
int overriddenKeyEvents = (mCustomMediaKeyDispatcher == null) ? 0
: mCustomMediaKeyDispatcher.getOverriddenKeyEvents().get(keyEvent.getKeyCode());
- cancelPendingIfNeeded(keyEvent);
- if (!needPending(keyEvent, overriddenKeyEvents)) {
+ cancelTrackingIfNeeded(packageName, pid, uid, asSystemService, keyEvent, needWakeLock,
+ overriddenKeyEvents);
+ if (!needTracking(keyEvent, overriddenKeyEvents)) {
dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent,
needWakeLock);
return;
}
if (isFirstDownKeyEvent(keyEvent)) {
- mPendingFirstDownKeyEvent = keyEvent;
+ mTrackingFirstDownKeyEvent = keyEvent;
mIsLongPressing = false;
return;
}
+ // Long press is always overridden here, otherwise the key event would have been already
+ // handled
if (isFirstLongPressKeyEvent(keyEvent)) {
mIsLongPressing = true;
}
if (mIsLongPressing) {
handleLongPressLocked(keyEvent, needWakeLock, overriddenKeyEvents);
- } else if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
- mPendingFirstDownKeyEvent = null;
- // TODO: Replace this with code to determine whether
- // single/double/triple click and run custom implementations,
- // if they exist.
- dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
+ return;
+ }
+
+ if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
+ mTrackingFirstDownKeyEvent = null;
+ if (shouldTrackForMultipleTapsLocked(overriddenKeyEvents)) {
+ if (mMultiTapCount == 0) {
+ mMultiTapTimeoutRunnable = createSingleTapRunnable(packageName, pid, uid,
+ asSystemService, keyEvent, needWakeLock,
+ isSingleTapOverridden(overriddenKeyEvents));
+ if (isSingleTapOverridden(overriddenKeyEvents)
+ && !isDoubleTapOverridden(overriddenKeyEvents)
+ && !isTripleTapOverridden(overriddenKeyEvents)) {
+ mMultiTapTimeoutRunnable.run();
+ } else {
+ mHandler.postDelayed(mMultiTapTimeoutRunnable,
+ MULTI_TAP_TIMEOUT);
+ mMultiTapCount = 1;
+ mMultiTapKeyCode = keyEvent.getKeyCode();
+ }
+ } else if (mMultiTapCount == 1) {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ mMultiTapTimeoutRunnable = createDoubleTapRunnable(packageName, pid, uid,
+ asSystemService, keyEvent, needWakeLock,
+ isSingleTapOverridden(overriddenKeyEvents),
+ isDoubleTapOverridden(overriddenKeyEvents));
+ if (isTripleTapOverridden(overriddenKeyEvents)) {
+ mHandler.postDelayed(mMultiTapTimeoutRunnable, MULTI_TAP_TIMEOUT);
+ mMultiTapCount = 2;
+ } else {
+ mMultiTapTimeoutRunnable.run();
+ }
+ } else if (mMultiTapCount == 2) {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ onTripleTap(keyEvent);
+ }
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ }
}
}
- private void cancelPendingIfNeeded(KeyEvent keyEvent) {
- if (mPendingFirstDownKeyEvent == null) {
+ private boolean shouldTrackForMultipleTapsLocked(int overriddenKeyEvents) {
+ return isSingleTapOverridden(overriddenKeyEvents)
+ || isDoubleTapOverridden(overriddenKeyEvents)
+ || isTripleTapOverridden(overriddenKeyEvents);
+ }
+
+ private void cancelTrackingIfNeeded(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ int overriddenKeyEvents) {
+ if (mTrackingFirstDownKeyEvent == null && mMultiTapTimeoutRunnable == null) {
return;
}
+
if (isFirstDownKeyEvent(keyEvent)) {
if (mLongPressTimeoutRunnable != null) {
mHandler.removeCallbacks(mLongPressTimeoutRunnable);
mLongPressTimeoutRunnable.run();
- } else {
- resetLongPressTracking();
}
+ if (mMultiTapTimeoutRunnable != null && keyEvent.getKeyCode() != mMultiTapKeyCode) {
+ runExistingMultiTapRunnableLocked();
+ }
+ resetLongPressTracking();
return;
}
- if (mPendingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime()
- && mPendingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode()
- && keyEvent.getAction() == KeyEvent.ACTION_DOWN
- && keyEvent.getRepeatCount() > 1 && !mIsLongPressing) {
- resetLongPressTracking();
+
+ if (mTrackingFirstDownKeyEvent != null
+ && mTrackingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime()
+ && mTrackingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode()
+ && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ if (isFirstLongPressKeyEvent(keyEvent)) {
+ if (mMultiTapTimeoutRunnable != null) {
+ runExistingMultiTapRunnableLocked();
+ }
+ if ((overriddenKeyEvents & KEY_EVENT_LONG_PRESS) == 0
+ && !isVoiceKey(keyEvent.getKeyCode())) {
+ dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
+ mTrackingFirstDownKeyEvent, needWakeLock);
+ mTrackingFirstDownKeyEvent = null;
+ }
+ } else if (keyEvent.getRepeatCount() > 1 && !mIsLongPressing) {
+ resetLongPressTracking();
+ }
}
}
- private boolean needPending(KeyEvent keyEvent, int overriddenKeyEvents) {
+ private boolean needTracking(KeyEvent keyEvent, int overriddenKeyEvents) {
if (!isFirstDownKeyEvent(keyEvent)) {
- if (mPendingFirstDownKeyEvent == null) {
+ if (mTrackingFirstDownKeyEvent == null) {
return false;
- } else if (mPendingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime()
- || mPendingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) {
+ } else if (mTrackingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime()
+ || mTrackingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) {
return false;
}
}
@@ -2193,10 +2264,21 @@ public class MediaSessionService extends SystemService implements Monitor {
return true;
}
+ private void runExistingMultiTapRunnableLocked() {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ mMultiTapTimeoutRunnable.run();
+ }
+
+ private void resetMultiTapTrackingLocked() {
+ mMultiTapCount = 0;
+ mMultiTapTimeoutRunnable = null;
+ mMultiTapKeyCode = 0;
+ }
+
private void handleLongPressLocked(KeyEvent keyEvent, boolean needWakeLock,
int overriddenKeyEvents) {
if (mCustomMediaKeyDispatcher != null
- && mCustomMediaKeyDispatcher.isLongPressOverridden(overriddenKeyEvents)) {
+ && isLongPressOverridden(overriddenKeyEvents)) {
mCustomMediaKeyDispatcher.onLongPress(keyEvent);
if (mLongPressTimeoutRunnable != null) {
@@ -2230,7 +2312,7 @@ public class MediaSessionService extends SystemService implements Monitor {
}
private void resetLongPressTracking() {
- mPendingFirstDownKeyEvent = null;
+ mTrackingFirstDownKeyEvent = null;
mIsLongPressing = false;
mLongPressTimeoutRunnable = null;
}
@@ -2259,6 +2341,50 @@ public class MediaSessionService extends SystemService implements Monitor {
keyEvent, needWakeLock);
}
+ Runnable createSingleTapRunnable(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ boolean overridden) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ resetMultiTapTrackingLocked();
+ if (overridden) {
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ }
+ }
+ };
+ };
+
+ Runnable createDoubleTapRunnable(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ boolean singleTapOverridden, boolean doubleTapOverridden) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ resetMultiTapTrackingLocked();
+ if (doubleTapOverridden) {
+ mCustomMediaKeyDispatcher.onDoubleTap(keyEvent);
+ } else if (singleTapOverridden) {
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ }
+ }
+ };
+ };
+
+ private void onTripleTap(KeyEvent keyEvent) {
+ resetMultiTapTrackingLocked();
+ mCustomMediaKeyDispatcher.onTripleTap(keyEvent);
+ }
+
private void dispatchMediaKeyEventLocked(String packageName, int pid, int uid,
boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
if (mCurrentFullUserRecord.getMediaButtonSessionLocked()
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 91979564fe96..ef6655dd224e 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -23,7 +23,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Process;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Pair;
@@ -140,7 +139,7 @@ public class OverlayActorEnforcer {
return ActorState.MISSING_LEGACY_PERMISSION;
}
}
- } catch (RemoteException | IOException e) {
+ } catch (IOException e) {
return ActorState.ERROR_READING_OVERLAYABLE;
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index c81f7cd4a8b4..84e43fcc9056 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1151,9 +1151,8 @@ public final class OverlayManagerService extends SystemService {
@Override
public boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
- throws RemoteException, IOException {
- PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, 0,
- userId);
+ throws IOException {
+ PackageInfo packageInfo = getPackageInfo(targetPackageName, userId);
if (packageInfo == null) {
throw new IOException("Unable to get target package");
}
diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
index 6b818849c257..5066ecdd6316 100644
--- a/services/core/java/com/android/server/om/OverlayableInfoCallback.java
+++ b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
@@ -22,7 +22,6 @@ import android.annotation.Nullable;
import android.content.om.OverlayableInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.os.RemoteException;
import com.android.server.pm.PackageManagerServiceUtils;
@@ -68,8 +67,7 @@ public interface OverlayableInfoCallback {
/**
* @return true if the target package has declared an overlayable
*/
- boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
- throws RemoteException, IOException;
+ boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
/**
* @throws SecurityException containing message if the caller doesn't have the given
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 1d5c30438870..385ace8a511b 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -746,9 +746,8 @@ public class LauncherAppsService extends SystemService {
}
UserHandle user = UserHandle.of(injectCallingUserId());
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
- == PackageManager.PERMISSION_GRANTED) {
+ if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(),
+ injectBinderCallingUid())) {
user = null;
}
@@ -1053,29 +1052,6 @@ public class LauncherAppsService extends SystemService {
}
public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback {
-
- static class QueryInfo {
- final long mChangedSince;
- final String mPackage;
- final List<String> mShortcutIds;
- final List<LocusId> mLocusIds;
- final ComponentName mActivity;
- final int mQueryFlags;
- final UserHandle mCallbackUser;
-
- QueryInfo(long changedSince, String packageName, List<String> shortcutIds,
- List<LocusId> locusIds, ComponentName activity, int flags,
- UserHandle callbackUser) {
- mChangedSince = changedSince;
- mPackage = packageName;
- mShortcutIds = shortcutIds;
- mLocusIds = locusIds;
- mActivity = activity;
- mQueryFlags = flags;
- mCallbackUser = callbackUser;
- }
- }
-
private final UserManagerInternal mUserManagerInternal;
ShortcutChangeHandler(UserManagerInternal userManager) {
@@ -1088,9 +1064,7 @@ public class LauncherAppsService extends SystemService {
public synchronized void addShortcutChangeCallback(IShortcutChangeCallback callback,
ShortcutQueryWrapper query, UserHandle user) {
mCallbacks.unregister(callback);
- mCallbacks.register(callback, new QueryInfo(query.getChangedSince(),
- query.getPackage(), query.getShortcutIds(), query.getLocusIds(),
- query.getActivity(), query.getQueryFlags(), user));
+ mCallbacks.register(callback, new Pair<>(query, user));
}
public synchronized void removeShortcutChangeCallback(
@@ -1116,16 +1090,19 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < count; i++) {
final IShortcutChangeCallback callback = mCallbacks.getBroadcastItem(i);
- final QueryInfo query = (QueryInfo) mCallbacks.getBroadcastCookie(i);
+ final Pair<ShortcutQueryWrapper, UserHandle> cookie =
+ (Pair<ShortcutQueryWrapper, UserHandle>)
+ mCallbacks.getBroadcastCookie(i);
- if (query.mCallbackUser != null && !hasUserAccess(query.mCallbackUser, user)) {
+ final UserHandle callbackUser = cookie.second;
+ if (callbackUser != null && !hasUserAccess(callbackUser, user)) {
// Callback owner does not have access to the shortcuts' user.
continue;
}
// Filter the list by query, if any matches exists, send via callback.
- List<ShortcutInfo> matchedList =
- filterShortcutsByQuery(packageName, shortcuts, query);
+ List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts,
+ cookie.first, shortcutsRemoved);
if (!CollectionUtils.isEmpty(matchedList)) {
try {
if (shortcutsRemoved) {
@@ -1143,21 +1120,25 @@ public class LauncherAppsService extends SystemService {
}
public static List<ShortcutInfo> filterShortcutsByQuery(String packageName,
- List<ShortcutInfo> shortcuts, QueryInfo query) {
- if (query.mPackage != null && query.mPackage != packageName) {
+ List<ShortcutInfo> shortcuts, ShortcutQueryWrapper query,
+ boolean shortcutsRemoved) {
+ final long changedSince = query.getChangedSince();
+ final String queryPackage = query.getPackage();
+ final List<String> shortcutIds = query.getShortcutIds();
+ final List<LocusId> locusIds = query.getLocusIds();
+ final ComponentName activity = query.getActivity();
+ final int flags = query.getQueryFlags();
+
+ if (queryPackage != null && !queryPackage.equals(packageName)) {
return null;
}
List<ShortcutInfo> matches = new ArrayList<>();
- final boolean matchDynamic =
- (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
- final boolean matchPinned =
- (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
- final boolean matchManifest =
- (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
- final boolean matchCached =
- (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0;
+ final boolean matchDynamic = (flags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
+ final boolean matchPinned = (flags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
+ final boolean matchManifest = (flags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
+ final boolean matchCached = (flags & ShortcutQuery.FLAG_MATCH_CACHED) != 0;
final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0)
| (matchPinned ? ShortcutInfo.FLAG_PINNED : 0)
| (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
@@ -1166,24 +1147,19 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < shortcuts.size(); i++) {
final ShortcutInfo si = shortcuts.get(i);
- if (query.mActivity != null && !query.mActivity.equals(si.getActivity())) {
+ if (activity != null && !activity.equals(si.getActivity())) {
continue;
}
-
- if (query.mChangedSince != 0
- && query.mChangedSince > si.getLastChangedTimestamp()) {
+ if (changedSince != 0 && changedSince > si.getLastChangedTimestamp()) {
continue;
}
-
- if (query.mShortcutIds != null && !query.mShortcutIds.contains(si.getId())) {
+ if (shortcutIds != null && !shortcutIds.contains(si.getId())) {
continue;
}
-
- if (query.mLocusIds != null && !query.mLocusIds.contains(si.getLocusId())) {
+ if (locusIds != null && !locusIds.contains(si.getLocusId())) {
continue;
}
-
- if ((shortcutFlags & si.getFlags()) != 0) {
+ if (shortcutsRemoved || (shortcutFlags & si.getFlags()) != 0) {
matches.add(si);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 8e7eaf6e29fa..d9275f59cbda 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -163,6 +163,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final int MSG_STREAM_VALIDATE_AND_COMMIT = 1;
private static final int MSG_INSTALL = 2;
private static final int MSG_ON_PACKAGE_INSTALLED = 3;
+ private static final int MSG_SESSION_VERIFICATION_FAILURE = 4;
/** XML constants used for persisting a session */
static final String TAG_SESSION = "session";
@@ -449,6 +450,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
packageName, returnCode, message, extras);
break;
+ case MSG_SESSION_VERIFICATION_FAILURE:
+ final int error = msg.arg1;
+ final String detailMessage = (String) msg.obj;
+ onSessionVerificationFailure(error, detailMessage);
+ break;
}
return true;
@@ -1479,15 +1485,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
private PackageManagerException onSessionVerificationFailure(PackageManagerException e) {
+ onSessionVerificationFailure(e.error, ExceptionUtils.getCompleteMessage(e));
+ return e;
+ }
+
+ private void onSessionVerificationFailure(int error, String detailMessage) {
// Session is sealed but could not be verified, we need to destroy it.
destroyInternal();
// Dispatch message to remove session from PackageInstallerService.
- dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
-
- return e;
+ dispatchSessionFinished(error, detailMessage, null);
}
private void onDataLoaderUnrecoverable() {
+ if (TextUtils.isEmpty(mPackageName)) {
+ // The package has not been installed.
+ return;
+ }
final PackageManagerService packageManagerService = mPm;
final String packageName = mPackageName;
mHandler.post(() -> {
@@ -2610,12 +2623,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
case IDataLoaderStatusListener.DATA_LOADER_STOPPED:
case IDataLoaderStatusListener.DATA_LOADER_DESTROYED:
return;
- case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
- onDataLoaderUnrecoverable();
- return;
}
if (mDestroyed || mDataLoaderFinished) {
+ switch (status) {
+ case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
+ onDataLoaderUnrecoverable();
+ return;
+ }
return;
}
@@ -2623,9 +2638,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
IDataLoader dataLoader = dataLoaderManager.getDataLoader(dataLoaderId);
if (dataLoader == null) {
mDataLoaderFinished = true;
- onSessionVerificationFailure(
- new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
- "Failure to obtain data loader"));
+ dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failure to obtain data loader");
return;
}
@@ -2670,14 +2684,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
case IDataLoaderStatusListener.DATA_LOADER_IMAGE_NOT_READY: {
mDataLoaderFinished = true;
- onSessionVerificationFailure(
- new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
- "Failed to prepare image."));
+ dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failed to prepare image.");
if (manualStartAndDestroy) {
dataLoader.destroy(dataLoaderId);
}
break;
}
+ case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
+ mDataLoaderFinished = true;
+ dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "DataLoader reported unrecoverable failure.");
+ return;
}
} catch (RemoteException e) {
// In case of streaming failure we don't want to fail or commit the session.
@@ -2708,6 +2726,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return false;
}
+ private void dispatchSessionVerificationFailure(int error, String detailMessage) {
+ mHandler.obtainMessage(MSG_SESSION_VERIFICATION_FAILURE, error, -1,
+ detailMessage).sendToTarget();
+ }
+
@Override
public int[] getChildSessionIds() {
final int[] childSessionIds = mChildSessionIds.copyKeys();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8b191dda5590..90ca83e0770f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17122,7 +17122,12 @@ public class PackageManagerService extends IPackageManager.Stub
// "updating same package" could also involve key-rotation.
final boolean sigsOk;
final String sourcePackageName = bp.getSourcePackageName();
- final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
+ final PackageSetting sourcePackageSetting;
+ synchronized (mLock) {
+ sourcePackageSetting = mSettings.getPackageLPr(sourcePackageName);
+ }
+ final SigningDetails sourceSigningDetails = (sourcePackageSetting == null
+ ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails());
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (sourcePackageName.equals(parsedPackage.getPackageName())
&& (ksms.shouldCheckUpgradeKeySetLocked(
@@ -17133,18 +17138,19 @@ public class PackageManagerService extends IPackageManager.Stub
// in the event of signing certificate rotation, we need to see if the
// package's certificate has rotated from the current one, or if it is an
// older certificate with which the current is ok with sharing permissions
- if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
+ if (sourceSigningDetails.checkCapability(
parsedPackage.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
sigsOk = true;
} else if (parsedPackage.getSigningDetails().checkCapability(
- sourcePackageSetting.signatures.mSigningDetails,
+ sourceSigningDetails,
PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
-
// the scanned package checks out, has signing certificate rotation
// history, and is newer; bring it over
- sourcePackageSetting.signatures.mSigningDetails =
- parsedPackage.getSigningDetails();
+ synchronized (mLock) {
+ sourcePackageSetting.signatures.mSigningDetails =
+ parsedPackage.getSigningDetails();
+ }
sigsOk = true;
} else {
sigsOk = false;
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 1fc0a38e1ed3..71a4bb431985 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -256,7 +256,7 @@ class ShortcutPackage extends ShortcutPackageItem {
if (shortcut != null) {
mShortcutUser.mService.removeIconLocked(shortcut);
shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
- | ShortcutInfo.FLAG_MANIFEST);
+ | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED);
}
return shortcut;
}
@@ -281,8 +281,10 @@ class ShortcutPackage extends ShortcutPackageItem {
* invisible.
*
* It checks the max number of dynamic shortcuts.
+ *
+ * @return True if it replaced an existing shortcut, False otherwise.
*/
- public void addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) {
+ public boolean addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) {
Preconditions.checkArgument(newShortcut.isEnabled(),
"add/setDynamicShortcuts() cannot publish disabled shortcuts");
@@ -291,38 +293,59 @@ class ShortcutPackage extends ShortcutPackageItem {
final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
+ final boolean replaced;
+
final boolean wasPinned;
+ final boolean wasCached;
if (oldShortcut == null) {
+ replaced = false;
wasPinned = false;
+ wasCached = false;
} else {
// It's an update case.
// Make sure the target is updatable. (i.e. should be mutable.)
oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false);
+ replaced = true;
wasPinned = oldShortcut.isPinned();
+ wasCached = oldShortcut.isCached();
}
// If it was originally pinned, the new one should be pinned too.
if (wasPinned) {
newShortcut.addFlags(ShortcutInfo.FLAG_PINNED);
}
+ if (wasCached) {
+ newShortcut.addFlags(ShortcutInfo.FLAG_CACHED);
+ }
forceReplaceShortcutInner(newShortcut);
+ return replaced;
}
/**
* Push a shortcut. If the max number of dynamic shortcuts is already reached, remove the
* shortcut with the lowest rank before adding the new shortcut.
+ *
+ * Any shortcut that gets altered (removed or changed) as a result of this push operation will
+ * be included and returned in changedShortcuts.
+ *
+ * @return True if a shortcut had to be removed to complete this operation, False otherwise.
*/
- public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut) {
+ public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut,
+ @NonNull List<ShortcutInfo> changedShortcuts) {
Preconditions.checkArgument(newShortcut.isEnabled(),
"pushDynamicShortcuts() cannot publish disabled shortcuts");
newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
+ changedShortcuts.clear();
final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
boolean wasPinned = false;
+ boolean wasCached = false;
+
+ boolean deleted = false;
if (oldShortcut == null) {
final ShortcutService service = mShortcutUser.mService;
@@ -343,10 +366,11 @@ class ShortcutPackage extends ShortcutPackageItem {
// All shortcuts are manifest shortcuts and cannot be removed.
Slog.e(TAG, "Failed to remove manifest shortcut while pushing dynamic shortcut "
+ newShortcut.getId());
- return false;
+ return true; // poppedShortcuts is empty which indicates a failure.
}
- deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true);
+ changedShortcuts.add(shortcut);
+ deleted = deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true) != null;
}
} else {
// It's an update case.
@@ -354,15 +378,19 @@ class ShortcutPackage extends ShortcutPackageItem {
oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false);
wasPinned = oldShortcut.isPinned();
+ wasCached = oldShortcut.isCached();
}
- // If it was originally pinned, the new one should be pinned too.
+ // If it was originally pinned or cached, the new one should be pinned or cached too.
if (wasPinned) {
newShortcut.addFlags(ShortcutInfo.FLAG_PINNED);
}
+ if (wasCached) {
+ newShortcut.addFlags(ShortcutInfo.FLAG_CACHED);
+ }
forceReplaceShortcutInner(newShortcut);
- return true;
+ return deleted;
}
/**
@@ -371,8 +399,7 @@ class ShortcutPackage extends ShortcutPackageItem {
* @return List of removed shortcuts.
*/
private List<ShortcutInfo> removeOrphans() {
- ArrayList<String> removeList = null; // Lazily initialize.
- List<ShortcutInfo> removedShortcuts = null;
+ List<ShortcutInfo> removeList = null;
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
@@ -381,18 +408,16 @@ class ShortcutPackage extends ShortcutPackageItem {
if (removeList == null) {
removeList = new ArrayList<>();
- removedShortcuts = new ArrayList<>();
}
- removeList.add(si.getId());
- removedShortcuts.add(si);
+ removeList.add(si);
}
if (removeList != null) {
for (int i = removeList.size() - 1; i >= 0; i--) {
- forceDeleteShortcutInner(removeList.get(i));
+ forceDeleteShortcutInner(removeList.get(i).getId());
}
}
- return removedShortcuts;
+ return removeList;
}
/**
@@ -424,68 +449,69 @@ class ShortcutPackage extends ShortcutPackageItem {
* Remove a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
* is pinned or cached, it'll remain as a pinned or cached shortcut, and is still enabled.
*
- * @return true if it's removed, or false if it was not actually removed because it is either
+ * @return The deleted shortcut, or null if it was not actually removed because it is either
* pinned or cached.
*/
- public boolean deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
- final ShortcutInfo removed = deleteOrDisableWithId(
+ public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
+ return deleteOrDisableWithId(
shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
- return removed == null;
}
/**
- * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
+ * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
* is pinned, it'll remain as a pinned shortcut, but will be disabled.
*
- * @return true if it's actually removed because it wasn't pinned, or false if it's still
- * pinned.
+ * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if
+ * it's still pinned.
*/
- private boolean disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible,
+ private ShortcutInfo disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible,
int disabledReason) {
- final ShortcutInfo disabled = deleteOrDisableWithId(
- shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible,
- disabledReason);
- return disabled == null;
+ return deleteOrDisableWithId(shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false,
+ ignoreInvisible, disabledReason);
}
/**
* Remove a long lived shortcut by ID. If the shortcut is pinned, it'll remain as a pinned
* shortcut, and is still enabled.
*
- * @return true if it's actually removed because it wasn't pinned, or false if it's still
- * pinned.
+ * @return The deleted shortcut, or null if it was not actually removed because it's pinned.
*/
- public boolean deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
+ public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
final ShortcutInfo shortcut = mShortcuts.get(shortcutId);
if (shortcut != null) {
shortcut.clearFlags(ShortcutInfo.FLAG_CACHED);
}
- final ShortcutInfo removed = deleteOrDisableWithId(
+ return deleteOrDisableWithId(
shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
- return removed == null;
}
/**
* Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
* is pinned, it'll remain as a pinned shortcut but will be disabled.
+ *
+ * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if
+ * it's still pinned.
*/
- public void disableWithId(@NonNull String shortcutId, String disabledMessage,
+ public ShortcutInfo disableWithId(@NonNull String shortcutId, String disabledMessage,
int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible,
int disabledReason) {
- final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true,
+ final ShortcutInfo deleted = deleteOrDisableWithId(shortcutId, /* disable =*/ true,
overrideImmutable, ignoreInvisible, disabledReason);
+ // If disabled id still exists, it is pinned and we need to update the disabled message.
+ final ShortcutInfo disabled = mShortcuts.get(shortcutId);
if (disabled != null) {
if (disabledMessage != null) {
disabled.setDisabledMessage(disabledMessage);
} else if (disabledMessageResId != 0) {
disabled.setDisabledMessageResId(disabledMessageResId);
-
mShortcutUser.mService.fixUpShortcutResourceNamesAndValues(disabled);
}
}
+
+ return deleted;
}
@Nullable
@@ -521,10 +547,10 @@ class ShortcutPackage extends ShortcutPackageItem {
oldShortcut.setActivity(null);
}
- return oldShortcut;
+ return null;
} else {
forceDeleteShortcutInner(shortcutId);
- return null;
+ return oldShortcut;
}
}
@@ -762,7 +788,7 @@ class ShortcutPackage extends ShortcutPackageItem {
// Get the list of all dynamic shortcuts in this package.
final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isDynamicVisible,
+ findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
@@ -807,7 +833,8 @@ class ShortcutPackage extends ShortcutPackageItem {
// Get the list of all dynamic shortcuts in this package
final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isDynamicVisible, ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+ findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
+ ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
int sharingShortcutCount = 0;
for (int i = 0; i < shortcuts.size(); i++) {
@@ -1004,7 +1031,7 @@ class ShortcutPackage extends ShortcutPackageItem {
"%s is no longer main activity. Disabling shorcut %s.",
getPackageName(), si.getId()));
if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false,
- ShortcutInfo.DISABLED_REASON_APP_CHANGED)) {
+ ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) {
continue; // Actually removed.
}
// Still pinned, so fall-through and possibly update the resources.
diff --git a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
index 6fd997db8be8..d4a02a9ceb2a 100644
--- a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
+++ b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
@@ -35,7 +35,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -513,10 +513,6 @@ class ShortcutRequestPinProcessor {
launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId,
/*forPinRequest=*/ true);
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
- }
- changedShortcuts.add(original);
if (current == null) {
if (DEBUG) {
@@ -526,6 +522,8 @@ class ShortcutRequestPinProcessor {
}
ps.adjustRanks(); // Shouldn't be needed, but just in case.
+
+ changedShortcuts = Collections.singletonList(ps.findShortcutById(shortcutId));
}
mService.verifyStates();
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 8d53d1554619..e4ae007dadee 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1666,11 +1666,10 @@ public class ShortcutService extends IShortcutService.Stub {
* - Write to file
*/
void packageShortcutsChanged(@NonNull String packageName, @UserIdInt int userId,
- @Nullable List<ShortcutInfo> addedOrUpdatedShortcuts,
- @Nullable List<ShortcutInfo> removedShortcuts) {
+ @Nullable final List<ShortcutInfo> changedShortcuts,
+ @Nullable final List<ShortcutInfo> removedShortcuts) {
notifyListeners(packageName, userId);
- notifyShortcutChangeCallbacks(packageName, userId, addedOrUpdatedShortcuts,
- removedShortcuts);
+ notifyShortcutChangeCallbacks(packageName, userId, changedShortcuts, removedShortcuts);
scheduleSaveUser(userId);
}
@@ -1699,8 +1698,11 @@ public class ShortcutService extends IShortcutService.Stub {
}
private void notifyShortcutChangeCallbacks(@NonNull String packageName, @UserIdInt int userId,
- @Nullable List<ShortcutInfo> addedOrUpdatedShortcuts,
- @Nullable List<ShortcutInfo> removedShortcuts) {
+ @Nullable final List<ShortcutInfo> changedShortcuts,
+ @Nullable final List<ShortcutInfo> removedShortcuts) {
+ final List<ShortcutInfo> changedList = removeNonKeyFields(changedShortcuts);
+ final List<ShortcutInfo> removedList = removeNonKeyFields(removedShortcuts);
+
final UserHandle user = UserHandle.of(userId);
injectPostToHandler(() -> {
try {
@@ -1713,12 +1715,11 @@ public class ShortcutService extends IShortcutService.Stub {
copy = new ArrayList<>(mShortcutChangeCallbacks);
}
for (int i = copy.size() - 1; i >= 0; i--) {
- if (!CollectionUtils.isEmpty(addedOrUpdatedShortcuts)) {
- copy.get(i).onShortcutsAddedOrUpdated(packageName, addedOrUpdatedShortcuts,
- user);
+ if (!CollectionUtils.isEmpty(changedList)) {
+ copy.get(i).onShortcutsAddedOrUpdated(packageName, changedList, user);
}
- if (!CollectionUtils.isEmpty(removedShortcuts)) {
- copy.get(i).onShortcutsRemoved(packageName, removedShortcuts, user);
+ if (!CollectionUtils.isEmpty(removedList)) {
+ copy.get(i).onShortcutsRemoved(packageName, removedList, user);
}
}
} catch (Exception ignore) {
@@ -1726,6 +1727,25 @@ public class ShortcutService extends IShortcutService.Stub {
});
}
+ private List<ShortcutInfo> removeNonKeyFields(@Nullable List<ShortcutInfo> shortcutInfos) {
+ if (CollectionUtils.isEmpty(shortcutInfos)) {
+ return shortcutInfos;
+ }
+
+ final int size = shortcutInfos.size();
+ List<ShortcutInfo> keyFieldOnlyShortcuts = new ArrayList<>(size);
+
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo si = shortcutInfos.get(i);
+ if (si.hasKeyFieldsOnly()) {
+ keyFieldOnlyShortcuts.add(si);
+ } else {
+ keyFieldOnlyShortcuts.add(si.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO));
+ }
+ }
+ return keyFieldOnlyShortcuts;
+ }
+
/**
* Clean up / validate an incoming shortcut.
* - Make sure all mandatory fields are set.
@@ -1820,6 +1840,7 @@ public class ShortcutService extends IShortcutService.Stub {
final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
injectBinderCallingPid(), injectBinderCallingUid());
+ List<ShortcutInfo> changedShortcuts = null;
List<ShortcutInfo> removedShortcuts = null;
synchronized (mLock) {
@@ -1846,7 +1867,12 @@ public class ShortcutService extends IShortcutService.Stub {
fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
}
- // First, remove all un-pinned; dynamic shortcuts
+ ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
+ ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isDynamic() && (si.isCached() || si.isPinned()),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
+ // First, remove all un-pinned and non-cached; dynamic shortcuts
removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
// Then, add/update all. We need to make sure to take over "pinned" flag.
@@ -1857,8 +1883,12 @@ public class ShortcutService extends IShortcutService.Stub {
// Lastly, adjust the ranks.
ps.adjustRanks();
+
+ changedShortcuts = prepareChangedShortcuts(
+ cachedOrPinned, newShortcuts, removedShortcuts, ps);
}
- packageShortcutsChanged(packageName, userId, newShortcuts, removedShortcuts);
+
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
verifyStates();
@@ -1916,6 +1946,11 @@ public class ShortcutService extends IShortcutService.Stub {
"ShortcutInfo.enabled cannot be changed with updateShortcuts()");
}
+ if (target.isLongLived() != source.isLongLived()) {
+ Slog.w(TAG,
+ "ShortcutInfo.longLived cannot be changed with updateShortcuts()");
+ }
+
// When updating the rank, we need to insert between existing ranks, so set
// this setRankChanged, and also copy the implicit rank fo adjustRanks().
if (source.hasRank()) {
@@ -2026,8 +2061,8 @@ public class ShortcutService extends IShortcutService.Stub {
verifyCaller(packageName, userId);
verifyShortcutInfoPackage(packageName, shortcut);
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ List<ShortcutInfo> changedShortcuts = new ArrayList<>();
+ List<ShortcutInfo> removedShortcuts = null;
synchronized (mLock) {
throwIfUserLockedL(userId);
@@ -2052,14 +2087,22 @@ public class ShortcutService extends IShortcutService.Stub {
shortcut.setRankChanged();
// Push it.
- if (!ps.pushDynamicShortcut(shortcut)) {
- return;
+ boolean deleted = ps.pushDynamicShortcut(shortcut, changedShortcuts);
+
+ if (deleted) {
+ if (changedShortcuts.isEmpty()) {
+ return; // Failed to push.
+ }
+ removedShortcuts = Collections.singletonList(changedShortcuts.get(0));
+ changedShortcuts.clear();
}
+ changedShortcuts.add(shortcut);
// Lastly, adjust the ranks.
ps.adjustRanks();
}
- packageShortcutsChanged(packageName, userId, Collections.singletonList(shortcut), null);
+
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
verifyStates();
}
@@ -2147,6 +2190,9 @@ public class ShortcutService extends IShortcutService.Stub {
verifyCaller(packageName, userId);
Objects.requireNonNull(shortcutIds, "shortcutIds must be provided");
+ List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> removedShortcuts = null;
+
synchronized (mLock) {
throwIfUserLockedL(userId);
@@ -2163,17 +2209,30 @@ public class ShortcutService extends IShortcutService.Stub {
if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
continue;
}
- ps.disableWithId(id,
+
+ final ShortcutInfo deleted = ps.disableWithId(id,
disabledMessageString, disabledMessageResId,
/* overrideImmutable=*/ false, /*ignoreInvisible=*/ true,
ShortcutInfo.DISABLED_REASON_BY_APP);
+
+ if (deleted == null) {
+ if (changedShortcuts == null) {
+ changedShortcuts = new ArrayList<>(1);
+ }
+ changedShortcuts.add(ps.findShortcutById(id));
+ } else {
+ if (removedShortcuts == null) {
+ removedShortcuts = new ArrayList<>(1);
+ }
+ removedShortcuts.add(deleted);
+ }
}
// We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks.
ps.adjustRanks();
}
- // TODO: Disabling dynamic shortcuts will removed them if not pinned. Cover all cases.
- packageShortcutsChanged(packageName, userId, null, null);
+
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
verifyStates();
}
@@ -2200,13 +2259,10 @@ public class ShortcutService extends IShortcutService.Stub {
}
ps.enableWithId(id);
- final ShortcutInfo si = ps.findShortcutById(id);
- if (si != null) {
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
- }
- changedShortcuts.add(si);
+ if (changedShortcuts == null) {
+ changedShortcuts = new ArrayList<>(1);
}
+ changedShortcuts.add(ps.findShortcutById(id));
}
}
@@ -2237,18 +2293,18 @@ public class ShortcutService extends IShortcutService.Stub {
if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
continue;
}
- final ShortcutInfo si = ps.findShortcutById(id);
- final boolean removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true);
- if (removed) {
- if (removedShortcuts == null) {
- removedShortcuts = new ArrayList<>(1);
- }
- removedShortcuts.add(si);
- } else {
+
+ ShortcutInfo removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true);
+ if (removed == null) {
if (changedShortcuts == null) {
changedShortcuts = new ArrayList<>(1);
}
- changedShortcuts.add(si);
+ changedShortcuts.add(ps.findShortcutById(id));
+ } else {
+ if (removedShortcuts == null) {
+ removedShortcuts = new ArrayList<>(1);
+ }
+ removedShortcuts.add(removed);
}
}
@@ -2264,7 +2320,7 @@ public class ShortcutService extends IShortcutService.Stub {
public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> changedShortcuts = new ArrayList<>();
List<ShortcutInfo> removedShortcuts = null;
synchronized (mLock) {
@@ -2272,10 +2328,16 @@ public class ShortcutService extends IShortcutService.Stub {
final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ // Dynamic shortcuts that are either cached or pinned will not get deleted.
+ ps.findAll(changedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isDynamic() && (si.isCached() || si.isPinned()),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
+ changedShortcuts = prepareChangedShortcuts(
+ changedShortcuts, null, removedShortcuts, ps);
}
- // TODO: Pinned and cached shortcuts are not removed, add those to changedShortcuts list
packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
verifyStates();
@@ -2300,22 +2362,21 @@ public class ShortcutService extends IShortcutService.Stub {
for (int i = shortcutIds.size() - 1; i >= 0; i--) {
final String id = Preconditions.checkStringNotEmpty((String) shortcutIds.get(i));
+ if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
+ continue;
+ }
- final ShortcutInfo si = ps.findShortcutById(id);
- final boolean removed = ps.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true);
-
- if (si != null) {
- if (removed) {
- if (removedShortcuts == null) {
- removedShortcuts = new ArrayList<>(1);
- }
- removedShortcuts.add(si);
- } else {
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
- }
- changedShortcuts.add(si);
+ ShortcutInfo removed = ps.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true);
+ if (removed != null) {
+ if (removedShortcuts == null) {
+ removedShortcuts = new ArrayList<>(1);
+ }
+ removedShortcuts.add(removed);
+ } else {
+ if (changedShortcuts == null) {
+ changedShortcuts = new ArrayList<>(1);
}
+ changedShortcuts.add(ps.findShortcutById(id));
}
}
@@ -2939,6 +3000,7 @@ public class ShortcutService extends IShortcutService.Stub {
Objects.requireNonNull(shortcutIds, "shortcutIds");
List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> removedShortcuts = null;
synchronized (mLock) {
throwIfUserLockedL(userId);
@@ -2948,24 +3010,31 @@ public class ShortcutService extends IShortcutService.Stub {
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
launcher.attemptToRestoreIfNeededAndSave();
- launcher.pinShortcuts(userId, packageName, shortcutIds, /*forPinRequest=*/ false);
-
final ShortcutPackage sp = getUserShortcutsLocked(userId)
.getPackageShortcutsIfExists(packageName);
if (sp != null) {
- for (int i = 0; i < shortcutIds.size(); i++) {
- final ShortcutInfo si = sp.findShortcutById(shortcutIds.get(i));
- if (si != null) {
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
- }
- changedShortcuts.add(si);
- }
+ // List the shortcuts that are pinned only, these will get removed.
+ removedShortcuts = new ArrayList<>();
+ sp.findAll(removedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isPinned() && !si.isCached() && !si.isDynamic()
+ && !si.isDeclaredInManifest(), ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO,
+ callingPackage, launcherUserId, false);
+ }
+ // Get list of shortcuts that will get unpinned.
+ ArraySet<String> oldPinnedIds = launcher.getPinnedShortcutIds(packageName, userId);
+
+ launcher.pinShortcuts(userId, packageName, shortcutIds, /*forPinRequest=*/ false);
+
+ if (oldPinnedIds != null && removedShortcuts != null) {
+ for (int i = 0; i < removedShortcuts.size(); i++) {
+ oldPinnedIds.remove(removedShortcuts.get(i).getId());
}
}
+ changedShortcuts = prepareChangedShortcuts(
+ oldPinnedIds, new ArraySet<>(shortcutIds), removedShortcuts, sp);
}
- // TODO: Include previously pinned shortcuts since they are not pinned anymore.
- packageShortcutsChanged(packageName, userId, changedShortcuts, null);
+
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
verifyStates();
}
@@ -3045,17 +3114,17 @@ public class ShortcutService extends IShortcutService.Stub {
+ "shortcut " + si.getId());
}
} else {
- boolean removed = false;
+ ShortcutInfo removed = null;
if (si.isDynamic()) {
si.clearFlags(ShortcutInfo.FLAG_CACHED);
} else {
removed = sp.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true);
}
- if (removed) {
+ if (removed != null) {
if (removedShortcuts == null) {
removedShortcuts = new ArrayList<>(1);
}
- removedShortcuts.add(si);
+ removedShortcuts.add(removed);
} else {
if (changedShortcuts == null) {
changedShortcuts = new ArrayList<>(1);
@@ -3222,8 +3291,6 @@ public class ShortcutService extends IShortcutService.Stub {
// Grant read uri permission to the caller on behalf of the shortcut owner. All
// granted permissions are revoked when the default launcher changes, or when
// device is rebooted.
- // b/151572645 is tracking a bug where Uri permissions are persisted across
- // reboots, even when Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION is not used.
mUriGrantsManager.grantUriPermissionFromOwner(mUriPermissionOwner, packageUid,
launcherPackage, Uri.parse(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION,
userId, launcherUserId);
@@ -4872,4 +4939,61 @@ public class ShortcutService extends IShortcutService.Stub {
mShortcutBitmapSaver.waitForAllSavesLocked();
}
}
+
+ /**
+ * This helper method does the following 3 tasks:
+ *
+ * 1- Combines the |changed| and |updated| shortcut lists, while removing duplicates.
+ * 2- If a shortcut is deleted and added at once in the same operation, removes it from the
+ * |removed| list.
+ * 3- Reloads the final list to get the latest flags.
+ */
+ private List<ShortcutInfo> prepareChangedShortcuts(ArraySet<String> changedIds,
+ ArraySet<String> newIds, List<ShortcutInfo> deletedList, final ShortcutPackage ps) {
+ if (ps == null) {
+ // This can happen when package restore is not finished yet.
+ return null;
+ }
+ if (CollectionUtils.isEmpty(changedIds) && CollectionUtils.isEmpty(newIds)) {
+ return null;
+ }
+
+ ArraySet<String> resultIds = new ArraySet<>();
+ if (!CollectionUtils.isEmpty(changedIds)) {
+ resultIds.addAll(changedIds);
+ }
+ if (!CollectionUtils.isEmpty(newIds)) {
+ resultIds.addAll(newIds);
+ }
+
+ if (!CollectionUtils.isEmpty(deletedList)) {
+ deletedList.removeIf((ShortcutInfo si) -> resultIds.contains(si.getId()));
+ }
+
+ List<ShortcutInfo> result = new ArrayList<>();
+ ps.findAll(result, (ShortcutInfo si) -> resultIds.contains(si.getId()),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+ return result;
+ }
+
+ private List<ShortcutInfo> prepareChangedShortcuts(List<ShortcutInfo> changedList,
+ List<ShortcutInfo> newList, List<ShortcutInfo> deletedList, final ShortcutPackage ps) {
+ ArraySet<String> changedIds = new ArraySet<>();
+ addShortcutIdsToSet(changedIds, changedList);
+
+ ArraySet<String> newIds = new ArraySet<>();
+ addShortcutIdsToSet(newIds, newList);
+
+ return prepareChangedShortcuts(changedIds, newIds, deletedList, ps);
+ }
+
+ private void addShortcutIdsToSet(ArraySet<String> ids, List<ShortcutInfo> shortcuts) {
+ if (CollectionUtils.isEmpty(shortcuts)) {
+ return;
+ }
+ final int size = shortcuts.size();
+ for (int i = 0; i < size; i++) {
+ ids.add(shortcuts.get(i).getId());
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 1d7d0388eb0a..cfa0449aaf33 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -31,7 +31,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionInfo;
-import android.content.pm.Signature;
import android.content.pm.parsing.component.ParsedPermission;
import android.os.UserHandle;
import android.util.Log;
@@ -86,9 +85,6 @@ public final class BasePermission {
String sourcePackageName;
- // TODO: Can we get rid of this? Seems we only use some signature info from the setting
- PackageSettingBase sourcePackageSetting;
-
int protectionLevel;
ParsedPermission perm;
@@ -130,12 +126,6 @@ public final class BasePermission {
public String getSourcePackageName() {
return sourcePackageName;
}
- public PackageSettingBase getSourcePackageSetting() {
- return sourcePackageSetting;
- }
- public Signature[] getSourceSignatures() {
- return sourcePackageSetting.getSignatures();
- }
public int getType() {
return type;
}
@@ -149,9 +139,6 @@ public final class BasePermission {
public void setPermission(@Nullable ParsedPermission perm) {
this.perm = perm;
}
- public void setSourcePackageSetting(PackageSettingBase sourcePackageSetting) {
- this.sourcePackageSetting = sourcePackageSetting;
- }
public int[] computeGids(int userId) {
if (perUser) {
@@ -290,7 +277,6 @@ public final class BasePermission {
return;
}
sourcePackageName = newPackageName;
- sourcePackageSetting = null;
perm = null;
if (pendingPermissionInfo != null) {
pendingPermissionInfo.packageName = newPackageName;
@@ -319,10 +305,9 @@ public final class BasePermission {
if (PackageManagerService.DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
+ getName() + " pkg=" + getSourcePackageName()
+ " info=" + pendingPermissionInfo);
- if (sourcePackageSetting == null && pendingPermissionInfo != null) {
+ if (pendingPermissionInfo != null) {
final BasePermission tree = findPermissionTree(permissionTrees, name);
if (tree != null && tree.perm != null) {
- sourcePackageSetting = tree.sourcePackageSetting;
perm = new ParsedPermission(tree.perm, pendingPermissionInfo,
tree.perm.getPackageName(), name);
uid = tree.uid;
@@ -355,7 +340,6 @@ public final class BasePermission {
if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
// It's a built-in permission and no owner, take ownership now
p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED);
- bp.sourcePackageSetting = pkgSetting;
bp.perm = p;
bp.uid = pkg.getUid();
bp.sourcePackageName = p.getPackageName();
@@ -378,7 +362,6 @@ public final class BasePermission {
if (tree == null
|| tree.sourcePackageName.equals(p.getPackageName())) {
p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED);
- bp.sourcePackageSetting = pkgSetting;
bp.perm = p;
bp.uid = pkg.getUid();
bp.sourcePackageName = p.getPackageName();
@@ -639,9 +622,6 @@ public final class BasePermission {
pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.getFlags()));
}
}
- if (sourcePackageSetting != null) {
- pw.print(" packageSetting="); pw.println(sourcePackageSetting);
- }
if (READ_EXTERNAL_STORAGE.equals(name)) {
pw.print(" enforced=");
pw.println(readEnforced);
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index e4e526145167..f5fff7d8ab58 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2526,7 +2526,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
+ " checking " + permName + ": " + bp);
}
- if (bp == null || bp.getSourcePackageSetting() == null) {
+ if (bp == null || getSourcePackageSetting(bp) == null) {
if (packageOfInterest == null || packageOfInterest.equals(
pkg.getPackageName())) {
if (DEBUG_PERMISSIONS) {
@@ -3403,10 +3403,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// - or its signing certificate is a previous signing certificate of the defining
// package, and the defining package still trusts the old certificate for permissions
// - or it shares the above relationships with the system package
+ final PackageParser.SigningDetails sourceSigningDetails =
+ getSourcePackageSigningDetails(bp);
boolean allowed =
- pkg.getSigningDetails().hasAncestorOrSelf(
- bp.getSourcePackageSetting().getSigningDetails())
- || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
+ pkg.getSigningDetails().hasAncestorOrSelf(sourceSigningDetails)
+ || sourceSigningDetails.checkCapability(
pkg.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION)
|| pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
@@ -3576,6 +3577,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return allowed;
}
+ @NonNull
+ private PackageParser.SigningDetails getSourcePackageSigningDetails(
+ @NonNull BasePermission bp) {
+ final PackageSetting ps = getSourcePackageSetting(bp);
+ if (ps == null) {
+ return PackageParser.SigningDetails.UNKNOWN;
+ }
+ return ps.getSigningDetails();
+ }
+
+ @Nullable
+ private PackageSetting getSourcePackageSetting(@NonNull BasePermission bp) {
+ final String sourcePackageName = bp.getSourcePackageName();
+ return mPackageManagerInt.getPackageSetting(sourcePackageName);
+ }
+
private static boolean isProfileOwner(int uid) {
DevicePolicyManagerInternal dpmInternal =
LocalServices.getService(DevicePolicyManagerInternal.class);
@@ -4084,8 +4101,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (bp.isDynamic()) {
bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
}
- if (bp.getSourcePackageSetting() == null
- || !packageName.equals(bp.getSourcePackageName())) {
+ if (!packageName.equals(bp.getSourcePackageName())) {
+ // Not checking sourcePackageSetting because it can be null when
+ // the permission source package is the target package and the target package is
+ // being uninstalled,
continue;
}
// The target package is the source of the current permission
@@ -4123,9 +4142,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
bp.getSourcePackageName());
synchronized (mLock) {
if (sourcePkg != null && sourcePs != null) {
- if (bp.getSourcePackageSetting() == null) {
- bp.setSourcePackageSetting(sourcePs);
- }
continue;
}
Slog.w(TAG, "Removing dangling permission: " + bp.getName()
@@ -4200,8 +4216,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
while (it.hasNext()) {
final BasePermission bp = it.next();
- if (bp.getSourcePackageSetting() == null
- || !packageName.equals(bp.getSourcePackageName())) {
+ if (!packageName.equals(bp.getSourcePackageName())) {
+ // Not checking sourcePackageSetting because it can be null when
+ // the permission source package is the target package and the target package is
+ // being uninstalled,
continue;
}
// The target package is the source of the current permission tree
@@ -4227,9 +4245,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
bp.getSourcePackageName());
synchronized (mLock) {
if (sourcePkg != null && sourcePs != null) {
- if (bp.getSourcePackageSetting() == null) {
- bp.setSourcePackageSetting(sourcePs);
- }
continue;
}
Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
index ec394a224cd7..4bc774413ac0 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
@@ -47,6 +47,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
/**
* This is a decorator of an {@link ISoundTriggerMiddlewareService}, which enforces permissions and
@@ -123,7 +124,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
}
}
- private Boolean mCaptureState;
+ private AtomicReference<Boolean> mCaptureState = new AtomicReference<>();
private final @NonNull ISoundTriggerMiddlewareInternal mDelegate;
private final @NonNull Context mContext;
@@ -230,10 +231,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
} catch (Exception e) {
throw handleException(e);
} finally {
- // It is safe to lock here - local operation.
- synchronized (this) {
- mCaptureState = active;
- }
+ mCaptureState.set(active);
}
}
@@ -286,8 +284,9 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
@Override
public void dump(PrintWriter pw) {
synchronized (this) {
- pw.printf("Capture state is %s\n\n", mCaptureState == null ? "uninitialized"
- : (mCaptureState ? "active" : "inactive"));
+ Boolean captureState = mCaptureState.get();
+ pw.printf("Capture state is %s\n\n", captureState == null ? "uninitialized"
+ : (captureState ? "active" : "inactive"));
if (mModules != null) {
for (int handle : mModules.keySet()) {
final ModuleState module = mModules.get(handle);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 8edc84fc8f37..df53227e27fd 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1384,7 +1384,8 @@ class ActivityStarter {
final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask();
final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null);
mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
- targetTask.getTaskInfo(), homeTaskVisible, clearedTask);
+ targetTask.getTaskInfo(), homeTaskVisible, clearedTask,
+ targetTask.getTopNonFinishingActivity().isVisible());
}
}
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 537ca08f49fc..5efc9241a494 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -382,8 +382,8 @@ class Dimmer {
@Override
public void apply(SurfaceControl.Transaction t, SurfaceControl sc, long currentPlayTime) {
- float alpha = ((float) currentPlayTime / getDuration()) * (mToAlpha - mFromAlpha)
- + mFromAlpha;
+ final float fraction = getFraction(currentPlayTime);
+ final float alpha = fraction * (mToAlpha - mFromAlpha) + mFromAlpha;
t.setAlpha(sc, alpha);
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 656dca531a22..1b1898b76506 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -27,7 +27,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.graphics.Rect;
@@ -38,7 +37,6 @@ import android.os.Process;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
-import android.util.Log;
import android.util.Slog;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
@@ -138,18 +136,6 @@ final class InputMonitor {
// If there's a drag in flight, provide a pseudo-window to catch drag input
final boolean inDrag = mService.mDragDropController.dragDropActiveLocked();
- final boolean inPositioning =
- mService.mTaskPositioningController.isPositioningLocked();
- if (inPositioning) {
- if (DEBUG_TASK_POSITIONING) {
- Log.d(TAG_WM, "Inserting window handle for repositioning");
- }
- mService.mTaskPositioningController.showInputSurface(mInputTransaction,
- mDisplayId);
- } else {
- mService.mTaskPositioningController.hideInputSurface(mInputTransaction,
- mDisplayId);
- }
// Add all windows on the default display.
mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);
diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
index 7c1a6161236a..f0629fa953fc 100644
--- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
@@ -130,6 +130,16 @@ class LocalAnimationAdapter implements AnimationAdapter {
*/
default boolean needsEarlyWakeup() { return false; }
+ /**
+ * @return The fraction of the animation, returns 1 if duration is 0.
+ *
+ * @param currentPlayTime The current play time.
+ */
+ default float getFraction(float currentPlayTime) {
+ final float duration = getDuration();
+ return duration > 0 ? currentPlayTime / duration : 1.0f;
+ }
+
void dump(PrintWriter pw, String prefix);
default void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 86e081854597..90936efe6715 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -646,8 +646,8 @@ class ScreenRotationAnimation {
@Override
public void apply(SurfaceControl.Transaction t, SurfaceControl leash,
long currentPlayTime) {
- float fraction = (float)currentPlayTime / (float)getDuration();
- int color = (Integer) va.evaluate(fraction, startColor, endColor);
+ final float fraction = getFraction(currentPlayTime);
+ final int color = (Integer) va.evaluate(fraction, startColor, endColor);
Color middleColor = Color.valueOf(color);
rgbTmpFloat[0] = middleColor.red();
rgbTmpFloat[1] = middleColor.green();
diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java
index 0b1760dc5a1c..99f710bd8bd4 100644
--- a/services/core/java/com/android/server/wm/ShellRoot.java
+++ b/services/core/java/com/android/server/wm/ShellRoot.java
@@ -43,6 +43,8 @@ public class ShellRoot {
private WindowToken mToken;
private final IBinder.DeathRecipient mDeathRecipient;
private SurfaceControl mSurfaceControl = null;
+ private IWindow mAccessibilityWindow;
+ private IBinder.DeathRecipient mAccessibilityWindowDeath;
ShellRoot(@NonNull IWindow client, @NonNull DisplayContent dc, final int windowType) {
mDisplayContent = dc;
@@ -112,11 +114,14 @@ public class ShellRoot {
if (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
return null;
}
+ if (mAccessibilityWindow == null) {
+ return null;
+ }
WindowInfo windowInfo = WindowInfo.obtain();
windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId;
windowInfo.type = mToken.windowType;
windowInfo.layer = mToken.getWindowLayerFromType();
- windowInfo.token = mClient.asBinder();
+ windowInfo.token = mAccessibilityWindow.asBinder();
windowInfo.title = "Splitscreen Divider";
windowInfo.focused = false;
windowInfo.inPictureInPicture = false;
@@ -126,5 +131,29 @@ public class ShellRoot {
windowInfo.regionInScreen.set(regionRect);
return windowInfo;
}
+
+ void setAccessibilityWindow(IWindow window) {
+ if (mAccessibilityWindow != null) {
+ mAccessibilityWindow.asBinder().unlinkToDeath(mAccessibilityWindowDeath, 0);
+ }
+ mAccessibilityWindow = window;
+ if (mAccessibilityWindow != null) {
+ try {
+ mAccessibilityWindowDeath = () -> {
+ synchronized (mDisplayContent.mWmService.mGlobalLock) {
+ mAccessibilityWindow = null;
+ setAccessibilityWindow(null);
+ }
+ };
+ mAccessibilityWindow.asBinder().linkToDeath(mAccessibilityWindowDeath, 0);
+ } catch (RemoteException e) {
+ mAccessibilityWindow = null;
+ }
+ }
+ if (mDisplayContent.mWmService.mAccessibilityController != null) {
+ mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(
+ mDisplayContent.getDisplayId());
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 2115a591a6b7..44049b84de40 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -644,7 +644,7 @@ class Task extends WindowContainer<WindowContainer> {
return;
}
removeImmediately();
- if (!isRootTask) {
+ if (isLeafTask()) {
mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
}
}
@@ -2904,7 +2904,7 @@ class Task extends WindowContainer<WindowContainer> {
adjustBoundsForDisplayChangeIfNeeded(dc);
}
super.onDisplayChanged(dc);
- if (!isRootTask) {
+ if (isLeafTask()) {
final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY;
mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged(
mTaskId, displayId);
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index e4f10d9840b2..4b0e293e831e 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -123,7 +123,7 @@ class TaskChangeNotificationController {
private final TaskStackConsumer mNotifyActivityRestartAttempt = (l, m) -> {
SomeArgs args = (SomeArgs) m.obj;
l.onActivityRestartAttempt((RunningTaskInfo) args.arg1, args.argi1 != 0,
- args.argi2 != 0);
+ args.argi2 != 0, args.argi3 != 0);
};
private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
@@ -368,12 +368,13 @@ class TaskChangeNotificationController {
* running, but the task is either brought to the front or a new Intent is delivered to it.
*/
void notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
- boolean clearedTask) {
+ boolean clearedTask, boolean wasVisible) {
mHandler.removeMessages(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
final SomeArgs args = SomeArgs.obtain();
args.arg1 = task;
args.argi1 = homeTaskVisible ? 1 : 0;
args.argi2 = clearedTask ? 1 : 0;
+ args.argi3 = wasVisible ? 1 : 0;
final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
args);
forAllLocalListeners(mNotifyActivityRestartAttempt, msg);
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index be0d6f8a0b9f..c68b660bb76f 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -53,7 +53,6 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputWindowHandle;
import android.view.MotionEvent;
-import android.view.SurfaceControl;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -268,9 +267,7 @@ class TaskPositioner implements IBinder.DeathRecipient {
mDisplayContent.getDisplayRotation().pause();
// Notify InputMonitor to take mDragWindowHandle.
- final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
- mDisplayContent.getInputMonitor().updateInputWindowsImmediately(t);
- t.syncInputWindows().apply();
+ mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
@@ -301,6 +298,7 @@ class TaskPositioner implements IBinder.DeathRecipient {
return;
}
+ mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId());
mService.mInputManager.unregisterInputChannel(mServerChannel);
mInputEventReceiver.dispose();
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 2d303faa7921..d343daf46f13 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -55,6 +55,8 @@ class TaskPositioningController {
return mTaskPositioner != null;
}
+ final SurfaceControl.Transaction mTransaction;
+
InputWindowHandle getDragWindowHandleLocked() {
return mTaskPositioner != null ? mTaskPositioner.mDragWindowHandle : null;
}
@@ -65,16 +67,18 @@ class TaskPositioningController {
mInputManager = inputManager;
mActivityManager = activityManager;
mHandler = new Handler(looper);
+ mTransaction = service.mTransactionFactory.get();
}
- void hideInputSurface(SurfaceControl.Transaction t, int displayId) {
+ void hideInputSurface(int displayId) {
if (mPositioningDisplay != null && mPositioningDisplay.getDisplayId() == displayId
&& mInputSurface != null) {
- t.hide(mInputSurface);
+ mTransaction.hide(mInputSurface);
+ mTransaction.syncInputWindows().apply();
}
}
- void showInputSurface(SurfaceControl.Transaction t, int displayId) {
+ void showInputSurface(int displayId) {
if (mPositioningDisplay == null || mPositioningDisplay.getDisplayId() != displayId) {
return;
}
@@ -92,16 +96,17 @@ class TaskPositioningController {
return;
}
- t.show(mInputSurface);
- t.setInputWindowInfo(mInputSurface, h);
- t.setLayer(mInputSurface, Integer.MAX_VALUE);
+ 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);
- t.setWindowCrop(mInputSurface, mTmpClipRect);
+ mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
+ mTransaction.syncInputWindows().apply();
}
boolean startMovingTask(IWindow window, float startX, float startY) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8eb4b2659cc0..84d749f148fb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -399,12 +399,18 @@ public class WindowManagerService extends IWindowManager.Stub
private static final String HIERARCHICAL_ANIMATIONS_PROPERTY =
"persist.wm.hierarchical_animations";
+ private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
+ "ro.sf.disable_triple_buffer";
+
/**
* @see #HIERARCHICAL_ANIMATIONS_PROPERTY
*/
static boolean sHierarchicalAnimations =
SystemProperties.getBoolean(HIERARCHICAL_ANIMATIONS_PROPERTY, true);
+ static boolean sEnableTripleBuffering = !SystemProperties.getBoolean(
+ DISABLE_TRIPLE_BUFFERING_PROPERTY, false);
+
// Enums for animation scale update types.
@Retention(RetentionPolicy.SOURCE)
@IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
@@ -1604,6 +1610,14 @@ public class WindowManagerService extends IWindowManager.Stub
// From now on, no exceptions or errors allowed!
res = WindowManagerGlobal.ADD_OKAY;
+
+ if (mUseBLAST) {
+ res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST;
+ }
+ if (sEnableTripleBuffering) {
+ res |= WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING;
+ }
+
if (displayContent.mCurrentFocus == null) {
displayContent.mWinAddedSinceNullFocus.add(win);
}
@@ -3897,6 +3911,30 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void setShellRootAccessibilityWindow(int displayId, int windowType, IWindow target) {
+ if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
+ }
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
+ if (dc == null) {
+ return;
+ }
+ ShellRoot root = dc.mShellRoots.get(windowType);
+ if (root == null) {
+ return;
+ }
+ root.setAccessibilityWindow(target);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
public void setDisplayWindowInsetsController(
int displayId, IDisplayWindowInsetsController insetsController) {
if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 1784e2186aa5..c4cb4b5091d8 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
+import static android.Manifest.permission.READ_FRAME_BUFFER;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
@@ -27,17 +28,20 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Slog;
+import android.view.Surface;
import android.view.SurfaceControl;
import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.util.function.pooled.PooledConsumer;
@@ -377,6 +381,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
mTransactionCallbacksByPendingSyncId.remove(mSyncId);
}
+ @Override
+ public boolean takeScreenshot(WindowContainerToken token, SurfaceControl outSurfaceControl) {
+ mService.mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "takeScreenshot()");
+ final WindowContainer wc = WindowContainer.fromBinder(token.asBinder());
+ if (wc == null) {
+ throw new RuntimeException("Invalid token in screenshot transaction");
+ }
+
+ final Rect bounds = new Rect();
+ wc.getBounds(bounds);
+ bounds.offsetTo(0, 0);
+ SurfaceControl.ScreenshotGraphicBuffer buffer = SurfaceControl.captureLayers(
+ wc.getSurfaceControl(), bounds, 1);
+
+ if (buffer == null || buffer.getGraphicBuffer() == null) {
+ return false;
+ }
+
+ SurfaceControl screenshot = mService.mWindowManager.mSurfaceControlFactory.apply(null)
+ .setName(wc.getName() + " - Organizer Screenshot")
+ .setBufferSize(bounds.width(), bounds.height())
+ .setFormat(PixelFormat.TRANSLUCENT)
+ .setParent(wc.getParentSurfaceControl())
+ .build();
+
+ Surface surface = new Surface();
+ surface.copyFrom(screenshot);
+ surface.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(), null);
+ surface.release();
+
+ outSurfaceControl.copyFrom(screenshot);
+ return true;
+ }
+
private void enforceStackPermission(String func) {
mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 706dcba31cfe..a3387ab42ab3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2491,6 +2491,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
/**
+ * Expands the given rectangle by the region of window resize handle for freeform window.
+ * @param inOutRect The rectangle to update.
+ */
+ private void adjustRegionInFreefromWindowMode(Rect inOutRect) {
+ if (!inFreeformWindowingMode()) {
+ return;
+ }
+
+ // For freeform windows, we need the touch region to include the whole
+ // surface for the shadows.
+ final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
+ final int delta = WindowManagerService.dipToPixel(
+ RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
+ inOutRect.inset(-delta, -delta);
+ }
+
+ /**
* Updates the region for a window in an Activity that was a touch modal. This will limit
* the outer touch to the activity stack region.
* @param outRegion The region to update.
@@ -2513,14 +2530,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
getRootTask().getDimBounds(mTmpRect);
}
}
- if (inFreeformWindowingMode()) {
- // For freeform windows, we need the touch region to include the whole
- // surface for the shadows.
- final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
- final int delta = WindowManagerService.dipToPixel(
- RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
- mTmpRect.inset(-delta, -delta);
- }
+ adjustRegionInFreefromWindowMode(mTmpRect);
outRegion.set(mTmpRect);
cropRegionToStackBoundsIfNeeded(outRegion);
}
@@ -3335,7 +3345,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
final ActivityStack stack = task.getStack();
- if (stack == null) {
+ if (stack == null || inFreeformWindowingMode()) {
return;
}
@@ -3354,6 +3364,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
stack.getDimBounds(mTmpRect);
+ adjustRegionInFreefromWindowMode(mTmpRect);
region.op(mTmpRect, Region.Op.INTERSECT);
}
@@ -5595,7 +5606,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
- final float fraction = (float) currentPlayTime / getDuration();
+ final float fraction = getFraction(currentPlayTime);
final float v = mInterpolator.getInterpolation(fraction);
t.setPosition(leash, mFrom.x + (mTo.x - mFrom.x) * v,
mFrom.y + (mTo.y - mFrom.y) * v);
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 55e6ab76188d..0a7ca5a0cf35 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -115,8 +115,8 @@ class WindowSurfaceController {
.setMetadata(METADATA_WINDOW_TYPE, windowType)
.setMetadata(METADATA_OWNER_UID, ownerUid);
- final boolean useBLAST = (win.getAttrs().privateFlags &
- WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0;
+ final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags &
+ WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
if (useBLAST) {
b.setContainerLayer();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5d5e424db017..7e4c8f3e48e5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7326,13 +7326,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return admin != null ? admin.mFactoryResetProtectionPolicy : null;
}
- private int getFrpManagementAgentUidOrThrow() {
+ private int getFrpManagementAgentUid() {
PersistentDataBlockManagerInternal pdb = mInjector.getPersistentDataBlockManagerInternal();
- if ((pdb == null) || (pdb.getAllowedUid() == -1)) {
+ return pdb != null ? pdb.getAllowedUid() : -1;
+ }
+
+ private int getFrpManagementAgentUidOrThrow() {
+ int uid = getFrpManagementAgentUid();
+ if (uid == -1) {
throw new UnsupportedOperationException(
"The persistent data block service is not supported on this device");
}
- return pdb.getAllowedUid();
+ return uid;
+ }
+
+ @Override
+ public boolean isFactoryResetProtectionPolicySupported() {
+ return getFrpManagementAgentUid() != -1;
}
@Override
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index cae5027250e1..10368586999c 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -761,10 +761,7 @@ int IncrementalService::unbind(StorageId storage, std::string_view target) {
std::unique_lock l2(ifs->lock);
if (ifs->bindPoints.size() <= 1) {
ifs->bindPoints.clear();
- std::thread([this, ifs, l2 = std::move(l2)]() mutable {
- mJni->initializeForCurrentThread();
- deleteStorageLocked(*ifs, std::move(l2));
- }).detach();
+ deleteStorageLocked(*ifs, std::move(l2));
} else {
const std::string savedFile = std::move(bindIt->second.savedFilename);
ifs->bindPoints.erase(bindIt);
diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
index fea61aa43442..dfe75ed50cd4 100644
--- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -30,10 +30,13 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import static org.testng.Assert.expectThrows;
import android.app.backup.BackupManager;
@@ -86,6 +89,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -104,6 +108,7 @@ public class UserBackupManagerServiceTest {
private static final String TAG = "BMSTest";
private static final String PACKAGE_1 = "some.package.1";
private static final String PACKAGE_2 = "some.package.2";
+ private static final String USER_FACING_PACKAGE = "user.facing.package";
private static final int USER_ID = 10;
@Mock private TransportManager mTransportManager;
@@ -1186,6 +1191,47 @@ public class UserBackupManagerServiceTest {
eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any());
}
+ @Test
+ public void testFilterUserFacingPackages_shouldSkipUserFacing_filtersUserFacing() {
+ List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE),
+ getPackageInfo(PACKAGE_1));
+ UserBackupManagerService backupManagerService = spy(
+ createUserBackupManagerServiceAndRunTasks());
+ when(backupManagerService.shouldSkipUserFacingData()).thenReturn(true);
+ when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true);
+
+ List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages(
+ packages);
+
+ assertFalse(containsPackage(filteredPackages, USER_FACING_PACKAGE));
+ assertTrue(containsPackage(filteredPackages, PACKAGE_1));
+ }
+
+ @Test
+ public void testFilterUserFacingPackages_shouldNotSkipUserFacing_doesNotFilterUserFacing() {
+ List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE),
+ getPackageInfo(PACKAGE_1));
+ UserBackupManagerService backupManagerService = spy(
+ createUserBackupManagerServiceAndRunTasks());
+ when(backupManagerService.shouldSkipUserFacingData()).thenReturn(false);
+ when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true);
+
+ List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages(
+ packages);
+
+ assertTrue(containsPackage(filteredPackages, USER_FACING_PACKAGE));
+ assertTrue(containsPackage(filteredPackages, PACKAGE_1));
+ }
+
+ private static boolean containsPackage(List<PackageInfo> packages, String targetPackage) {
+ for (PackageInfo packageInfo : packages) {
+ if (targetPackage.equals(packageInfo.packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() {
return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks(
USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index 064e3486823a..98f476464842 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -67,7 +67,7 @@ import java.util.concurrent.TimeUnit;
*/
public class SystemActionPerformerTest {
private static final int LATCH_TIMEOUT_MS = 500;
- private static final int LEGACY_SYSTEM_ACTION_COUNT = 9;
+ private static final int LEGACY_SYSTEM_ACTION_COUNT = 8;
private static final int NEW_ACTION_ID = 20;
private static final String LABEL_1 = "label1";
private static final String LABEL_2 = "label2";
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index a587029914a7..28887fdab00d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -24,6 +24,7 @@ import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
import static com.android.server.hdmi.Constants.ADDR_TUNER_1;
import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.Constants.MESSAGE_GIVE_AUDIO_STATUS;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
@@ -47,6 +48,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.ArrayList;
+
@SmallTest
@RunWith(JUnit4.class)
/** Tests for {@link HdmiCecLocalDeviceAudioSystem} class. */
@@ -167,6 +169,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
};
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+
mMyLooper = mTestLooper.getLooper();
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
@@ -717,4 +721,112 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mHdmiCecLocalDeviceAudioSystem.onHotplug(0, false);
assertThat(mWokenUp).isFalse();
}
+
+ @Test
+ public void giveAudioStatus_volumeEnabled() {
+ mMusicVolume = 50;
+ mMusicMaxVolume = 100;
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
+
+ int volume = mHdmiControlService.getAudioManager()
+ .getStreamVolume(AudioManager.STREAM_MUSIC);
+ boolean mute = mHdmiControlService.getAudioManager()
+ .isStreamMute(AudioManager.STREAM_MUSIC);
+ int maxVolume = mHdmiControlService.getAudioManager()
+ .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
+ HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
+ ADDR_TV, scaledVolume, mute);
+ HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
+
+ HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
+ ADDR_AUDIO_SYSTEM);
+ mNativeWrapper.clearResultMessages();
+ boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(expected);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
+ assertThat(handled).isTrue();
+ }
+
+ @Test
+ public void giveAudioStatus_volumeDisabled() {
+ mMusicVolume = 50;
+ mMusicMaxVolume = 100;
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
+
+ int volume = mHdmiControlService.getAudioManager()
+ .getStreamVolume(AudioManager.STREAM_MUSIC);
+ boolean mute = mHdmiControlService.getAudioManager()
+ .isStreamMute(AudioManager.STREAM_MUSIC);
+ int maxVolume = mHdmiControlService.getAudioManager()
+ .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
+ HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
+ ADDR_TV, scaledVolume, mute);
+ HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
+
+ HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
+ ADDR_AUDIO_SYSTEM);
+ mNativeWrapper.clearResultMessages();
+ boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
+ assertThat(handled).isTrue();
+ }
+
+ @Test
+ public void reportAudioStatus_volumeEnabled() {
+ mMusicVolume = 50;
+ mMusicMaxVolume = 100;
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
+
+ int volume = mHdmiControlService.getAudioManager()
+ .getStreamVolume(AudioManager.STREAM_MUSIC);
+ boolean mute = mHdmiControlService.getAudioManager()
+ .isStreamMute(AudioManager.STREAM_MUSIC);
+ int maxVolume = mHdmiControlService.getAudioManager()
+ .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
+ HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
+ ADDR_TV, scaledVolume, mute);
+
+ mNativeWrapper.clearResultMessages();
+ mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(expected);
+ }
+
+ @Test
+ public void reportAudioStatus_volumeDisabled() {
+ mMusicVolume = 50;
+ mMusicMaxVolume = 100;
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
+
+ int volume = mHdmiControlService.getAudioManager()
+ .getStreamVolume(AudioManager.STREAM_MUSIC);
+ boolean mute = mHdmiControlService.getAudioManager()
+ .isStreamMute(AudioManager.STREAM_MUSIC);
+ int maxVolume = mHdmiControlService.getAudioManager()
+ .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
+ HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
+ ADDR_TV, scaledVolume, mute);
+
+ mNativeWrapper.clearResultMessages();
+ mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index f72d622c00c3..b8394e3c1643 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Looper;
import android.os.test.TestLooper;
+import android.view.KeyEvent;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -153,4 +154,75 @@ public class HdmiCecLocalDevicePlaybackTest {
mHdmiCecLocalDevicePlayback.onHotplug(0, false);
assertThat(mWokenUp).isFalse();
}
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_up_volumeEnabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
+
+ assertThat(hasSendKeyAction()).isTrue();
+ }
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_down_volumeEnabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
+
+ assertThat(hasSendKeyAction()).isTrue();
+ }
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_mute_volumeEnabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
+
+ assertThat(hasSendKeyAction()).isTrue();
+ }
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_up_volumeDisabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
+
+ assertThat(hasSendKeyAction()).isFalse();
+ }
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_down_volumeDisabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
+
+ assertThat(hasSendKeyAction()).isFalse();
+ }
+
+ @Test
+ @Ignore("b/151147315")
+ public void sendVolumeKeyEvent_mute_volumeDisabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
+ mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
+
+ assertThat(hasSendKeyAction()).isFalse();
+ }
+
+ private boolean hasSendKeyAction() {
+ boolean match = false;
+ for (HdmiCecFeatureAction action : mHdmiCecLocalDevicePlayback.mActions) {
+ if (action instanceof SendKeyAction) {
+ match = true;
+ break;
+ }
+ }
+ return match;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index 039b90429395..e0bada3138e0 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -19,6 +19,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID;
@@ -185,4 +186,64 @@ public class HdmiCecLocalDeviceTest {
HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_AUDIO_SYSTEM));
assertTrue(mStandbyMessageReceived);
}
+
+ @Test
+ public void handleUserControlPressed_volumeUp() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void handleUserControlPressed_volumeDown() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void handleUserControlPressed_volumeMute() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_MUTE));
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void handleUserControlPressed_volumeUp_disabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void handleUserControlPressed_volumeDown_disabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void handleUserControlPressed_volumeMute_disabled() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ boolean result = mHdmiLocalDevice.handleUserControlPressed(
+ HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
+ HdmiCecKeycode.CEC_KEYCODE_MUTE));
+
+ assertFalse(result);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index fa19814f401f..7af7a23b1ef6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -252,4 +252,13 @@ public class HdmiControlServiceTest {
assertThat(mHdmiControlService.getPowerStatus()).isEqualTo(
HdmiControlManager.POWER_STATUS_STANDBY);
}
+
+ @Test
+ public void setAndGetCecVolumeControlEnabled_isApi() {
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
+ assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isFalse();
+
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
+ assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isTrue();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 06b344b3b94f..efa25bd7721b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -6734,6 +6734,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.hasShareTargets(CALLING_PACKAGE_1);
}
+ public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
+ setCaller(LAUNCHER_1, USER_0);
+
+ IntentFilter filter_any = new IntentFilter();
+ filter_any.addDataType("*/*");
+
+ assertExpectException(SecurityException.class, "Missing permission", () ->
+ mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ filter_any));
+
+ // Has permission, now it should pass.
+ mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
+ mManager.hasShareTargets(CALLING_PACKAGE_1);
+ }
+
public void testDumpsys_crossProfile() {
prepareCrossProfileDataSet();
dumpsysOnLogcat("test1", /* force= */ true);
@@ -8645,6 +8660,61 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
filter_any));
}
+ public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()
+ throws IntentFilter.MalformedMimeTypeException {
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_share_targets);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+ final ShortcutInfo s1 = makeShortcutWithCategory("s1",
+ set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2"));
+ final ShortcutInfo s2 = makeShortcutWithCategory("s2",
+ set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6"));
+ final ShortcutInfo s3 = makeShortcutWithCategory("s3",
+ set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6"));
+ s1.setLongLived();
+ s2.setLongLived();
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
+ assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
+ "s1", "s2", "s3");
+ });
+
+ IntentFilter filter_any = new IntentFilter();
+ filter_any.addDataType("*/*");
+
+ setCaller(LAUNCHER_1, USER_0);
+ mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
+
+ // Assert all are sharing shortcuts
+ assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ filter_any));
+ assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ filter_any));
+ assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
+ filter_any));
+
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ // Remove one cached shortcut, and leave one cached-only and pinned-only shortcuts.
+ mManager.removeLongLivedShortcuts(list("s1"));
+ mManager.removeDynamicShortcuts(list("s2, s3"));
+ });
+
+ assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ filter_any));
+ assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ filter_any));
+ assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
+ filter_any));
+ }
+
private Uri getFileUriFromResource(String fileName, int resId) throws IOException {
File file = new File(getTestContext().getFilesDir(), fileName);
// Make sure we are not leaving phantom files behind.
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
new file mode 100644
index 000000000000..50d290a837cd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.pm.LauncherApps.ShortcutChangeCallback;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.ShortcutInfo;
+import android.os.test.TestLooper;
+
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
+
+/**
+ * Tests for {@link android.content.pm.LauncherApps.ShortcutChangeCallback} and relevant APIs.
+ *
+ atest -c com.android.server.pm.ShortcutManagerTest11
+ */
+public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
+
+ private static final ShortcutQuery QUERY_MATCH_ALL = createShortcutQuery(
+ ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED);
+
+ private final TestLooper mTestLooper = new TestLooper();
+
+ public void testShortcutChangeCallback_setDynamicShortcuts() {
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2");
+ }
+
+ public void testShortcutChangeCallback_setDynamicShortcuts_replaceSameId() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s2", "s3")));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_setDynamicShortcuts_pinnedAndCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(
+ list(makeShortcut("s1"), makeLongLivedShortcut("s2"))));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s3", "s4")));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2", "s3", "s4");
+ }
+
+ public void testShortcutChangeCallback_pinShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_pinShortcuts_unpinOthers() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2", "s3")));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0);
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeDynamicShortcuts(list("s1", "s2"));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0);
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_cacheShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0);
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s3");
+ }
+
+ public void testShortcutChangeCallback_uncacheShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2");
+ }
+
+ public void testShortcutChangeCallback_uncacheShortcuts_causeDeletion() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeDynamicShortcuts(list("s2", "s3"));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0);
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s3");
+ }
+
+ public void testShortcutChangeCallback_updateShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
+ makeShortcutWithActivity("s2", new ComponentName(CALLING_PACKAGE_1, "test")))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ final ComponentName updatedCn = new ComponentName(CALLING_PACKAGE_1, "updated activity");
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.updateShortcuts(list(makeShortcutWithActivity("s2", updatedCn))));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2");
+ assertEquals(updatedCn, ((ShortcutInfo) shortcuts.getValue().get(0)).getActivity());
+ }
+
+ public void testShortcutChangeCallback_addDynamicShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.addDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2");
+ }
+
+ public void testShortcutChangeCallback_pushDynamicShortcut() {
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.pushDynamicShortcut(makeShortcut("s1"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_pushDynamicShortcut_existingId() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5",
+ "s6", "s7", "s8", "s9", "s10"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.pushDynamicShortcut(makeShortcut("s5"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s5");
+ }
+
+ public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletion() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5",
+ "s6", "s7", "s8", "s9", "s10"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.pushDynamicShortcut(makeShortcut("s11"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s11");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s10");
+ }
+
+ public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletionButCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5",
+ "s6", "s7", "s8", "s9"))));
+ ShortcutInfo s10 = makeLongLivedShortcut("s10");
+ s10.setRank(10);
+ mManager.pushDynamicShortcut(s10); // Add a long lived shortcut to the end of the list.
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s10"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.pushDynamicShortcut(makeShortcut("s11"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s10", "s11");
+ }
+
+ public void testShortcutChangeCallback_disableShortcuts() {
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.disableShortcuts(list("s2"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any());
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2");
+ }
+
+ public void testShortcutChangeCallback_disableShortcuts_pinnedAndCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(
+ list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.disableShortcuts(list("s1", "s2", "s3"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_enableShortcuts() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(
+ list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.disableShortcuts(list("s1", "s2", "s3"));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.enableShortcuts(list("s1", "s2", "s3"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+ }
+
+ public void testShortcutChangeCallback_removeDynamicShortcuts() {
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeDynamicShortcuts(list("s2"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any());
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2");
+ }
+
+ public void testShortcutChangeCallback_removeDynamicShortcuts_pinnedAndCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeDynamicShortcuts(list("s1", "s2", "s3"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_removeAllDynamicShortcuts() {
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeAllDynamicShortcuts();
+ });
+
+ mTestLooper.dispatchAll();
+
+ verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any());
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2");
+ }
+
+ public void testShortcutChangeCallback_removeAllDynamicShortcuts_pinnedAndCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(
+ list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeAllDynamicShortcuts();
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s2", "s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1");
+ }
+
+ public void testShortcutChangeCallback_removeLongLivedShortcuts_notCached() {
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeShortcut("s3"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeLongLivedShortcuts(list("s1", "s2"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any());
+
+ ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(shortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2");
+ }
+
+ public void testShortcutChangeCallback_removeLongLivedShortcuts_pinnedAndCached() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
+ makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4"))));
+ });
+
+ ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
+ mTestLooper.getNewExecutor());
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ mManager.removeLongLivedShortcuts(list("s1", "s2", "s3"));
+ });
+
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsAddedOrUpdated(
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onShortcutsRemoved(
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+
+ assertWith(changedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s3");
+
+ assertWith(removedShortcuts.getValue())
+ .areAllWithKeyFieldsOnly()
+ .haveIds("s1", "s2");
+ }
+
+ private static ShortcutQuery createShortcutQuery(int queryFlags) {
+ ShortcutQuery q = new ShortcutQuery();
+ return q.setQueryFlags(ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED);
+ }
+}
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 a84a0a2260b2..edc9756d6d0e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -808,6 +808,41 @@ public class ActivityStarterTests extends ActivityTestsBase {
verify(secondaryTaskContainer, times(2)).createStack(anyInt(), anyInt(), anyBoolean());
}
+ @Test
+ public void testWasVisibleInRestartAttempt() {
+ final ActivityStarter starter = prepareStarter(
+ FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP, false);
+ final ActivityRecord reusableActivity =
+ new ActivityBuilder(mService).setCreateTask(true).build();
+ final ActivityRecord topActivity =
+ new ActivityBuilder(mService).setCreateTask(true).build();
+
+ // Make sure topActivity is on top
+ topActivity.getRootTask().moveToFront("testWasVisibleInRestartAttempt");
+ reusableActivity.setVisible(false);
+
+ final TaskChangeNotificationController taskChangeNotifier =
+ mService.getTaskChangeNotificationController();
+ spyOn(taskChangeNotifier);
+
+ Task task = topActivity.getTask();
+ starter.postStartActivityProcessing(
+ task.getTopNonFinishingActivity(), START_DELIVERED_TO_TOP, task.getStack());
+
+ verify(taskChangeNotifier).notifyActivityRestartAttempt(
+ any(), anyBoolean(), anyBoolean(), anyBoolean());
+ verify(taskChangeNotifier).notifyActivityRestartAttempt(
+ any(), anyBoolean(), anyBoolean(), eq(true));
+
+ Task task2 = reusableActivity.getTask();
+ starter.postStartActivityProcessing(
+ task2.getTopNonFinishingActivity(), START_TASK_TO_FRONT, task.getStack());
+ verify(taskChangeNotifier, times(2)).notifyActivityRestartAttempt(
+ any(), anyBoolean(), anyBoolean(), anyBoolean());
+ verify(taskChangeNotifier).notifyActivityRestartAttempt(
+ any(), anyBoolean(), anyBoolean(), eq(false));
+ }
+
private ActivityRecord createSingleTaskActivityOn(ActivityStack stack) {
final ComponentName componentName = ComponentName.createRelative(
DEFAULT_COMPONENT_PACKAGE_NAME,
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 dea9294ff75b..bce1320f1d7e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -335,7 +335,11 @@ public class SystemServicesTestRule implements TestRule {
mWmService.mConstants.dispose();
mWmService.mHighRefreshRateBlacklist.dispose();
+ // This makes sure the posted messages without delay are processed, e.g.
+ // DisplayPolicy#release, WindowManagerService#setAnimationScale.
waitUntilWindowManagerHandlersIdle();
+ // Clear all posted messages with delay, so they don't be executed at unexpected times.
+ cleanupWindowManagerHandlers();
// Needs to explicitly dispose current static threads because there could be messages
// scheduled at a later time, and all mocks are invalid when it's executed.
DisplayThread.dispose();
@@ -399,8 +403,6 @@ public class SystemServicesTestRule implements TestRule {
if (wm == null) {
return;
}
- // Removing delayed FORCE_GC message decreases time for waiting idle.
- wm.mH.removeMessages(WindowManagerService.H.FORCE_GC);
waitHandlerIdle(wm.mH);
waitHandlerIdle(wm.mAnimationHandler);
// This is a different handler object than the wm.mAnimationHandler above.
@@ -408,25 +410,8 @@ public class SystemServicesTestRule implements TestRule {
waitHandlerIdle(SurfaceAnimationThread.getHandler());
}
- private void waitHandlerIdle(Handler handler) {
- synchronized (mCurrentMessagesProcessed) {
- // Add a message to the handler queue and make sure it is fully processed before we move
- // on. This makes sure all previous messages in the handler are fully processed vs. just
- // popping them from the message queue.
- mCurrentMessagesProcessed.set(false);
- handler.post(() -> {
- synchronized (mCurrentMessagesProcessed) {
- mCurrentMessagesProcessed.set(true);
- mCurrentMessagesProcessed.notifyAll();
- }
- });
- while (!mCurrentMessagesProcessed.get()) {
- try {
- mCurrentMessagesProcessed.wait();
- } catch (InterruptedException e) {
- }
- }
- }
+ static void waitHandlerIdle(Handler handler) {
+ handler.runWithScissors(() -> { }, 0 /* timeout */);
}
void waitUntilWindowAnimatorIdle() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 6e41118997ac..9872faaf6582 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
+import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityView;
import android.app.IActivityManager;
@@ -43,6 +44,7 @@ import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
+import android.view.Display;
import android.view.ViewGroup;
import androidx.test.filters.FlakyTest;
@@ -319,15 +321,91 @@ public class TaskStackChangedListenerTest {
waitForCallback(singleTaskDisplayEmptyLatch);
}
+ @Test
+ public void testTaskDisplayChanged() throws Exception {
+ final CountDownLatch activityViewReadyLatch = new CountDownLatch(1);
+ final ActivityViewTestActivity activity =
+ (ActivityViewTestActivity) startTestActivity(ActivityViewTestActivity.class);
+ final ActivityView activityView = activity.getActivityView();
+ activityView.setCallback(new ActivityView.StateCallback() {
+ @Override
+ public void onActivityViewReady(ActivityView view) {
+ activityViewReadyLatch.countDown();
+ }
+ @Override
+ public void onActivityViewDestroyed(ActivityView view) {}
+ });
+ waitForCallback(activityViewReadyLatch);
+
+ // Launch a Activity inside ActivityView.
+ final Object[] params1 = new Object[1];
+ final CountDownLatch displayChangedLatch1 = new CountDownLatch(1);
+ final int activityViewDisplayId = activityView.getVirtualDisplayId();
+ registerTaskStackChangedListener(
+ new TaskDisplayChangedListener(
+ activityViewDisplayId, params1, displayChangedLatch1));
+ int taskId1;
+ ActivityOptions options1 = ActivityOptions.makeBasic()
+ .setLaunchDisplayId(activityView.getVirtualDisplayId());
+ synchronized (sLock) {
+ taskId1 = startTestActivity(ActivityInActivityView.class, options1).getTaskId();
+ }
+ waitForCallback(displayChangedLatch1);
+
+ assertEquals(taskId1, params1[0]);
+
+ // Launch the Activity in the default display, expects that reparenting happens.
+ final Object[] params2 = new Object[1];
+ final CountDownLatch displayChangedLatch2 = new CountDownLatch(1);
+ registerTaskStackChangedListener(
+ new TaskDisplayChangedListener(
+ Display.DEFAULT_DISPLAY, params2, displayChangedLatch2));
+ int taskId2;
+ ActivityOptions options2 = ActivityOptions.makeBasic()
+ .setLaunchDisplayId(Display.DEFAULT_DISPLAY);
+ synchronized (sLock) {
+ taskId2 = startTestActivity(ActivityInActivityView.class, options2).getTaskId();
+ }
+ waitForCallback(displayChangedLatch2);
+
+ assertEquals(taskId2, params2[0]);
+ assertEquals(taskId1, taskId2); // TaskId should be same since reparenting happens.
+ }
+
+ private static class TaskDisplayChangedListener extends TaskStackListener {
+ private int mDisplayId;
+ private final Object[] mParams;
+ private final CountDownLatch mDisplayChangedLatch;
+ TaskDisplayChangedListener(
+ int displayId, Object[] params, CountDownLatch displayChangedLatch) {
+ mDisplayId = displayId;
+ mParams = params;
+ mDisplayChangedLatch = displayChangedLatch;
+ }
+ @Override
+ public void onTaskDisplayChanged(int taskId, int displayId) throws RemoteException {
+ // Filter out the events for the uninterested displays.
+ // if (displayId != mDisplayId) return;
+ mParams[0] = taskId;
+ mDisplayChangedLatch.countDown();
+ }
+ };
+
/**
* Starts the provided activity and returns the started instance.
*/
private TestActivity startTestActivity(Class<?> activityClass) throws InterruptedException {
+ return startTestActivity(activityClass, ActivityOptions.makeBasic());
+ }
+
+ private TestActivity startTestActivity(Class<?> activityClass, ActivityOptions options)
+ throws InterruptedException {
final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), null, false);
getInstrumentation().addMonitor(monitor);
final Context context = getInstrumentation().getContext();
context.startActivity(
- new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+ options.toBundle());
final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000);
if (activity == null) {
throw new RuntimeException("Timed out waiting for Activity");
@@ -337,6 +415,9 @@ public class TaskStackChangedListenerTest {
}
private void registerTaskStackChangedListener(ITaskStackListener listener) throws Exception {
+ if (mTaskStackListener != null) {
+ ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
+ }
mTaskStackListener = listener;
ActivityTaskManager.getService().registerTaskStackListener(listener);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 6a64d1c976c4..94c204ab0fe0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -52,13 +52,9 @@ import android.view.WindowManager;
import com.android.server.AttributeCache;
-import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
-import java.util.HashSet;
-import java.util.LinkedList;
-
/**
* Common base class for window manager unit test classes.
*
@@ -85,7 +81,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
WindowState mAppWindow;
WindowState mChildAppWindowAbove;
WindowState mChildAppWindowBelow;
- HashSet<WindowState> mCommonWindows;
/**
* Spied {@link Transaction} class than can be used to verify calls.
@@ -115,7 +110,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
mDisplayContent = createNewDisplay(true /* supportIme */);
// Set-up some common windows.
- mCommonWindows = new HashSet<>();
synchronized (mWm.mGlobalLock) {
mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
@@ -151,48 +145,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Called before display is created.
}
- @After
- public void tearDownBase() {
- // If @After throws an exception, the error isn't logged. This will make sure any failures
- // in the tear down are clear. This can be removed when b/37850063 is fixed.
- try {
- // Test may schedule to perform surface placement or other messages. Wait until a
- // stable state to clean up for consistency.
- waitUntilHandlersIdle();
-
- final LinkedList<WindowState> nonCommonWindows = new LinkedList<>();
-
- synchronized (mWm.mGlobalLock) {
- mWm.mRoot.forAllWindows(w -> {
- if (!mCommonWindows.contains(w)) {
- nonCommonWindows.addLast(w);
- }
- }, true /* traverseTopToBottom */);
-
- while (!nonCommonWindows.isEmpty()) {
- nonCommonWindows.pollLast().removeImmediately();
- }
-
- // Remove app transition & window freeze timeout callbacks to prevent unnecessary
- // actions after test.
- mWm.getDefaultDisplayContentLocked().mAppTransition
- .removeAppTransitionTimeoutCallbacks();
- mWm.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT);
- mDisplayContent.mInputMethodTarget = null;
- }
-
- // Cleaned up everything in Handler.
- cleanupWindowManagerHandlers();
- } catch (Exception e) {
- Log.e(TAG, "Failed to tear down test", e);
- throw e;
- }
- }
-
private WindowState createCommonWindow(WindowState parent, int type, String name) {
synchronized (mWm.mGlobalLock) {
final WindowState win = createWindow(parent, type, name);
- mCommonWindows.add(win);
// Prevent common windows from been IMe targets
win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
return win;
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index e7be43459e16..852b1244cd6e 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -263,6 +263,10 @@ class LinkCommand : public Command {
"Changes the name of the target package for instrumentation. Most useful\n"
"when used in conjunction with --rename-manifest-package.",
&options_.manifest_fixer_options.rename_instrumentation_target_package);
+ AddOptionalFlag("--rename-overlay-target-package",
+ "Changes the name of the target package for overlay. Most useful\n"
+ "when used in conjunction with --rename-manifest-package.",
+ &options_.manifest_fixer_options.rename_overlay_target_package);
AddOptionalFlagList("-0", "File suffix not to compress.",
&options_.extensions_to_not_compress);
AddOptionalSwitch("--no-compress", "Do not compress any resources.",
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index bcfce663db00..c813a446b8db 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -263,6 +263,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
}
}
+ if (options_.rename_overlay_target_package) {
+ if (!util::IsJavaPackageName(options_.rename_overlay_target_package.value())) {
+ diag->Error(DiagMessage()
+ << "invalid overlay target package override '"
+ << options_.rename_overlay_target_package.value()
+ << "'");
+ return false;
+ }
+ }
+
// Common <intent-filter> actions.
xml::XmlNodeAction intent_filter_action;
intent_filter_action["action"].Action(RequiredNameIsNotEmpty);
@@ -373,7 +383,17 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
manifest_action["attribution"];
manifest_action["attribution"]["inherit-from"];
manifest_action["original-package"];
- manifest_action["overlay"];
+ manifest_action["overlay"].Action([&](xml::Element* el) -> bool {
+ if (!options_.rename_overlay_target_package) {
+ return true;
+ }
+
+ if (xml::Attribute* attr =
+ el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
+ attr->value = options_.rename_overlay_target_package.value();
+ }
+ return true;
+ });
manifest_action["protected-broadcast"];
manifest_action["adopt-permissions"];
manifest_action["uses-permission"];
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index 3ef57d0d0e42..ec4367b450fb 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -44,6 +44,10 @@ struct ManifestFixerOptions {
// <instrumentation>.
Maybe<std::string> rename_instrumentation_target_package;
+ // The Android package to use instead of the one defined in 'android:targetPackage' in
+ // <overlay>.
+ Maybe<std::string> rename_overlay_target_package;
+
// The version name to set if 'android:versionName' is not defined in <manifest> or if
// replace_version is set.
Maybe<std::string> version_name_default;
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 3af06f53d4f3..0791805e2506 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -325,6 +325,32 @@ TEST_F(ManifestFixerTest,
EXPECT_THAT(attr->value, StrEq("com.android"));
}
+TEST_F(ManifestFixerTest,
+ RenameManifestOverlayPackageAndFullyQualifyTarget) {
+ ManifestFixerOptions options;
+ options.rename_overlay_target_package = std::string("com.android");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <overlay android:targetName="Customization" android:targetPackage="android" />
+ </manifest>)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Element* overlay_el =
+ manifest_el->FindChild({}, "overlay");
+ ASSERT_THAT(overlay_el, NotNull());
+
+ xml::Attribute* attr =
+ overlay_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("com.android"));
+}
+
TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
ManifestFixerOptions options;
options.version_name_default = std::string("Beta");