summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp23
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java34
-rw-r--r--core/api/current.txt11
-rw-r--r--core/api/test-current.txt1
-rw-r--r--core/java/android/app/Activity.java8
-rw-r--r--core/java/android/app/Notification.java1
-rw-r--r--core/java/android/app/admin/DeviceAdminInfo.java5
-rw-r--r--core/java/android/app/jank/JankTracker.java75
-rw-r--r--core/java/android/app/jank/flags.aconfig10
-rw-r--r--core/java/android/app/notification.aconfig10
-rw-r--r--core/java/android/companion/virtual/flags/flags.aconfig8
-rw-r--r--core/java/android/content/pm/multiuser.aconfig2
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java10
-rw-r--r--core/java/android/hardware/usb/IUsbManagerInternal.aidl26
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java12
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java13
-rw-r--r--core/java/android/os/ExternalVibration.java12
-rw-r--r--core/java/android/os/health/SystemHealthManager.java10
-rw-r--r--core/java/android/permission/flags.aconfig13
-rw-r--r--core/java/android/provider/Settings.java37
-rw-r--r--core/java/android/provider/Telephony.java67
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionManager.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--core/java/android/view/XrWindowProperties.java159
-rw-r--r--core/java/android/window/DesktopModeFlags.java8
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig32
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig30
-rw-r--r--core/java/android/window/flags/windowing_sdk.aconfig21
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHistory.java190
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHistoryIterator.java74
-rw-r--r--core/java/com/android/internal/policy/DecorView.java130
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java12
-rw-r--r--core/java/com/android/internal/widget/ActionBarOverlayLayout.java85
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java1
-rw-r--r--core/java/com/android/internal/widget/MessagingGroup.java13
-rw-r--r--core/java/com/android/internal/widget/MessagingLayout.java1
-rw-r--r--core/java/com/android/internal/widget/PeopleHelper.java2
-rw-r--r--core/jni/platform/host/HostRuntime.cpp14
-rw-r--r--core/res/res/values-af/strings.xml6
-rw-r--r--core/res/res/values-am/strings.xml6
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-as/strings.xml6
-rw-r--r--core/res/res/values-az/strings.xml6
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml3
-rw-r--r--core/res/res/values-be/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml6
-rw-r--r--core/res/res/values-bn/strings.xml6
-rw-r--r--core/res/res/values-bs/strings.xml6
-rw-r--r--core/res/res/values-ca/strings.xml6
-rw-r--r--core/res/res/values-cs/strings.xml6
-rw-r--r--core/res/res/values-da/strings.xml6
-rw-r--r--core/res/res/values-de/strings.xml6
-rw-r--r--core/res/res/values-el/strings.xml6
-rw-r--r--core/res/res/values-en-rAU/strings.xml6
-rw-r--r--core/res/res/values-en-rCA/strings.xml2
-rw-r--r--core/res/res/values-en-rGB/strings.xml6
-rw-r--r--core/res/res/values-en-rIN/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml6
-rw-r--r--core/res/res/values-et/strings.xml6
-rw-r--r--core/res/res/values-eu/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml6
-rw-r--r--core/res/res/values-fi/strings.xml6
-rw-r--r--core/res/res/values-fr-rCA/strings.xml6
-rw-r--r--core/res/res/values-fr/strings.xml6
-rw-r--r--core/res/res/values-gl/strings.xml6
-rw-r--r--core/res/res/values-gu/strings.xml3
-rw-r--r--core/res/res/values-hi/strings.xml6
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml6
-rw-r--r--core/res/res/values-hy/strings.xml6
-rw-r--r--core/res/res/values-in/strings.xml6
-rw-r--r--core/res/res/values-is/strings.xml6
-rw-r--r--core/res/res/values-it/strings.xml3
-rw-r--r--core/res/res/values-iw/strings.xml3
-rw-r--r--core/res/res/values-ja/strings.xml3
-rw-r--r--core/res/res/values-ka/strings.xml6
-rw-r--r--core/res/res/values-kk/strings.xml6
-rw-r--r--core/res/res/values-km/strings.xml6
-rw-r--r--core/res/res/values-kn/strings.xml6
-rw-r--r--core/res/res/values-ko/strings.xml6
-rw-r--r--core/res/res/values-ky/strings.xml6
-rw-r--r--core/res/res/values-lo/strings.xml6
-rw-r--r--core/res/res/values-lt/strings.xml6
-rw-r--r--core/res/res/values-lv/strings.xml6
-rw-r--r--core/res/res/values-mk/strings.xml8
-rw-r--r--core/res/res/values-ml/strings.xml3
-rw-r--r--core/res/res/values-mn/strings.xml6
-rw-r--r--core/res/res/values-mr/strings.xml6
-rw-r--r--core/res/res/values-ms/strings.xml3
-rw-r--r--core/res/res/values-my/strings.xml6
-rw-r--r--core/res/res/values-nb/strings.xml6
-rw-r--r--core/res/res/values-ne/strings.xml6
-rw-r--r--core/res/res/values-nl/strings.xml6
-rw-r--r--core/res/res/values-or/strings.xml3
-rw-r--r--core/res/res/values-pa/strings.xml3
-rw-r--r--core/res/res/values-pl/strings.xml6
-rw-r--r--core/res/res/values-pt-rBR/strings.xml6
-rw-r--r--core/res/res/values-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-ro/strings.xml6
-rw-r--r--core/res/res/values-ru/strings.xml6
-rw-r--r--core/res/res/values-si/strings.xml6
-rw-r--r--core/res/res/values-sk/strings.xml6
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-sq/strings.xml6
-rw-r--r--core/res/res/values-sr/strings.xml3
-rw-r--r--core/res/res/values-sv/strings.xml6
-rw-r--r--core/res/res/values-sw/strings.xml6
-rw-r--r--core/res/res/values-ta/strings.xml6
-rw-r--r--core/res/res/values-te/strings.xml6
-rw-r--r--core/res/res/values-th/strings.xml3
-rw-r--r--core/res/res/values-tl/strings.xml6
-rw-r--r--core/res/res/values-tr/strings.xml6
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-ur/strings.xml6
-rw-r--r--core/res/res/values-uz/strings.xml6
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml6
-rw-r--r--core/res/res/values-zh-rHK/strings.xml6
-rw-r--r--core/res/res/values-zh-rTW/strings.xml6
-rw-r--r--core/res/res/values-zu/strings.xml6
-rw-r--r--core/res/res/values/config.xml18
-rw-r--r--core/res/res/values/config_telephony.xml5
-rw-r--r--core/res/res/values/symbols.xml6
-rw-r--r--core/tests/coretests/src/android/app/NotificationTest.java10
-rw-r--r--core/tests/vibrator/src/android/os/ExternalVibrationTest.java18
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig10
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml14
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml6
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt61
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java82
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt96
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt190
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt72
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt25
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt17
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt22
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java38
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java27
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt87
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt36
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt47
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt524
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt101
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt19
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt47
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt136
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java35
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java2
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h10
-rw-r--r--libs/hwui/jni/Graphics.cpp13
-rw-r--r--media/java/Android.bp1
-rw-r--r--media/java/android/media/quality/Android.bp39
-rw-r--r--media/java/android/media/quality/MediaQualityManager.java86
-rw-r--r--media/java/android/media/quality/SoundProfileHandle.java72
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/ActiveProcessingPicture.aidl (renamed from media/java/android/media/quality/ActiveProcessingPicture.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightEvent.aidl (renamed from media/java/android/media/quality/AmbientBacklightEvent.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightMetadata.aidl (renamed from media/java/android/media/quality/AmbientBacklightMetadata.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightSettings.aidl (renamed from media/java/android/media/quality/AmbientBacklightSettings.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/IAmbientBacklightCallback.aidl (renamed from media/java/android/media/quality/IAmbientBacklightCallback.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl (renamed from media/java/android/media/quality/IMediaQualityManager.aidl)70
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/IPictureProfileCallback.aidl (renamed from media/java/android/media/quality/IPictureProfileCallback.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/ISoundProfileCallback.aidl (renamed from media/java/android/media/quality/ISoundProfileCallback.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/ParameterCapability.aidl (renamed from media/java/android/media/quality/ParameterCapability.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/PictureProfile.aidl (renamed from media/java/android/media/quality/PictureProfile.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/PictureProfileHandle.aidl (renamed from media/java/android/media/quality/PictureProfileHandle.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/SoundProfile.aidl (renamed from media/java/android/media/quality/SoundProfile.aidl)0
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/SoundProfileHandle.aidl (renamed from media/java/android/media/quality/SoundProfileHandle.aidl)5
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-az/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rAU/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rGB/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rIN/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ro/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml6
-rw-r--r--packages/EasterEgg/src/com/android/egg/landroid/UniverseProgressNotifier.kt2
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/Android.bp (renamed from packages/SettingsLib/SpaPrivileged/tests/Android.bp)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/AndroidManifest.xml (renamed from packages/SettingsLib/SpaPrivileged/tests/AndroidManifest.xml)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/res/values/strings.xml (renamed from packages/SettingsLib/SpaPrivileged/tests/res/values/strings.xml)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt)0
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt (renamed from packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt)0
-rw-r--r--packages/SettingsLib/aconfig/settingslib.aconfig17
-rw-r--r--packages/SettingsLib/res/drawable/ic_news.xml19
-rw-r--r--packages/SettingsLib/res/drawable/ic_promotions.xml19
-rw-r--r--packages/SettingsLib/res/drawable/ic_recs.xml25
-rw-r--r--packages/SettingsLib/res/drawable/ic_social.xml19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java13
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt1
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java26
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java1
-rw-r--r--packages/Shell/res/values-et/strings.xml2
-rw-r--r--packages/SystemUI/aconfig/predictive_back.aconfig7
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig9
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt25
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt5
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt1
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/PagerDots.kt (renamed from packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt)4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt32
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt9
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt40
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt11
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt42
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt261
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json38
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json34
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json12
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeEnter.json4
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeExit.json4
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/testAnchoredWidthOnly.json4
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json634
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json624
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json544
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json424
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json364
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json744
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json304
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json244
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt4
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt279
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt16
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredSizeTest.kt10
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/test/subjects/DpOffsetSubject.kt4
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt10
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt13
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt8
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt10
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/KairosCoreStartableTest.kt67
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt150
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java)22
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt36
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt30
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/log/LogWtfHandlerRuleTest.kt155
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt137
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt168
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt100
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt90
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt88
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateOverrideTest.kt105
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt32
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt19
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt49
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt30
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt59
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt32
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt211
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt95
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationCloseButtonTest.kt160
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt)47
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt370
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java339
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt61
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt23
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java23
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java19
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt)122
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt8
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt138
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt6
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt11
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/WeatherData.kt70
-rw-r--r--packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt (renamed from packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt)5
-rw-r--r--packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Main.java (renamed from packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Main.java)0
-rw-r--r--packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/UiBackground.java (renamed from packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java)0
-rw-r--r--packages/SystemUI/res-keyguard/drawable/qs_media_recommendation_bg_gradient.xml26
-rw-r--r--packages/SystemUI/res/drawable/qs_media_rec_scrim.xml25
-rw-r--r--packages/SystemUI/res/layout/magic_action_button.xml2
-rw-r--r--packages/SystemUI/res/layout/media_recommendation_view.xml90
-rw-r--r--packages/SystemUI/res/layout/media_recommendations.xml75
-rw-r--r--packages/SystemUI/res/layout/volume_dialog.xml6
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_top_section.xml2
-rw-r--r--packages/SystemUI/res/values-af/strings.xml14
-rw-r--r--packages/SystemUI/res/values-am/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml11
-rw-r--r--packages/SystemUI/res/values-as/strings.xml14
-rw-r--r--packages/SystemUI/res/values-az/strings.xml14
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml5
-rw-r--r--packages/SystemUI/res/values-be/strings.xml11
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml11
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml14
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-da/strings.xml14
-rw-r--r--packages/SystemUI/res/values-de/strings.xml14
-rw-r--r--packages/SystemUI/res/values-el/strings.xml11
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml14
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml10
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml14
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml14
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml11
-rw-r--r--packages/SystemUI/res/values-es/strings.xml14
-rw-r--r--packages/SystemUI/res/values-et/strings.xml11
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml11
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml5
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml11
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml11
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml14
-rw-r--r--packages/SystemUI/res/values-in/strings.xml14
-rw-r--r--packages/SystemUI/res/values-is/strings.xml14
-rw-r--r--packages/SystemUI/res/values-it/strings.xml2
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml14
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-km/strings.xml11
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml11
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml5
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml5
-rw-r--r--packages/SystemUI/res/values-my/strings.xml14
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml23
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-or/strings.xml5
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml5
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml11
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml14
-rw-r--r--packages/SystemUI/res/values-si/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml5
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sw720dp-land/dimens.xml5
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml14
-rw-r--r--packages/SystemUI/res/values-te/strings.xml14
-rw-r--r--packages/SystemUI/res/values-th/strings.xml5
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml20
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml11
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml14
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml14
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml18
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/res/values/styles.xml51
-rw-r--r--packages/SystemUI/res/xml/media_recommendations_collapsed.xml64
-rw-r--r--packages/SystemUI/res/xml/media_recommendations_expanded.xml71
-rw-r--r--packages/SystemUI/shared/Android.bp1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt11
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java306
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt270
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ClockEventController.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/KairosActivatable.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesChecker.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt99
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java102
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt156
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt469
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt196
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java494
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt79
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/view/RecommendationViewHolder.kt122
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt238
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt695
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardGutsViewModel.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardViewModel.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsButtonViewModel.kt (renamed from packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt)7
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsSettingsButtonViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSeekBarViewModel.kt57
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUIStateOverride.kt83
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUiState.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileListener.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt151
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt112
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java130
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java136
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt145
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTileGrid.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogComponentFactory.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogModule.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt3
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withAnimator.json)0
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withAnimator.json)0
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json)11
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json)11
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withAnimator.json)0
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json)11
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json)11
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json (renamed from packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withAnimator.json)0
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json492
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json375
-rw-r--r--packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json375
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt90
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt72
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt159
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt835
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt100
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt50
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt51
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractorTest.kt53
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/ui/viewmodel/BatteryViewModelTest.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/log/LogWtfHandlerRule.kt102
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt37
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt33
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt15
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt54
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponentKosmos.kt5
-rw-r--r--packages/Vcn/service-b/Android.bp5
-rw-r--r--packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java20
-rwxr-xr-xravenwood/scripts/list-ravenwood-tests.sh18
-rw-r--r--ravenwood/tools/hoststubgen/Android.bp15
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Exceptions.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Exceptions.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessor.kt165
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessorOptions.kt177
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenErrors.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenLogger.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenStats.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Utils.kt)22
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/AsmUtils.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/dumper/ApiDumper.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt)2
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AnnotationBasedFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ConstantFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DelegatingFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterRemapper.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/InMemoryOutputFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/KeepNativeFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/OutputFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/PackageFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/PackageFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SanitizationFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SubclassFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/ClassPredicate.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/OptionUtils.kt206
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/Trie.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/Trie.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BaseAdapter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/Helper.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/Helper.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt)0
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt218
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenMain.kt30
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt413
-rw-r--r--ravenwood/tools/ravenhelper/Android.bp6
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt88
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt2
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt82
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt2
-rw-r--r--ravenwood/tools/ravenizer/Android.bp6
-rw-r--r--ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerMain.kt25
-rw-r--r--ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt123
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java36
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java56
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java9
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilter.java66
-rw-r--r--services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java31
-rw-r--r--services/backup/java/com/android/server/backup/BackupRestoreTask.java31
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java47
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java2
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java38
-rw-r--r--services/backup/java/com/android/server/backup/internal/BackupHandler.java5
-rw-r--r--services/backup/java/com/android/server/backup/internal/LifecycleOperationStorage.java21
-rw-r--r--services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java10
-rw-r--r--services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java2
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java4
-rw-r--r--services/companion/java/com/android/server/companion/association/AssociationDiskStore.java14
-rw-r--r--services/core/Android.bp8
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java2
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java8
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java3
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java21
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java6
-rw-r--r--services/core/java/com/android/server/appop/AttributedOp.java11
-rw-r--r--services/core/java/com/android/server/appop/DiscreteOpsRegistry.java56
-rw-r--r--services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java11
-rw-r--r--services/core/java/com/android/server/appop/DiscreteOpsTestingShim.java8
-rw-r--r--services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java11
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java9
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java4
-rw-r--r--services/core/java/com/android/server/audio/SoundDoseHelper.java2
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java5
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java34
-rw-r--r--services/core/java/com/android/server/display/DisplayTopologyCoordinator.java21
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java389
-rw-r--r--services/core/java/com/android/server/input/InputGestureManager.java5
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java7
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java151
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java164
-rw-r--r--services/core/java/com/android/server/media/MediaRouterMetricLogger.java219
-rw-r--r--services/core/java/com/android/server/media/quality/MediaQualityService.java85
-rw-r--r--services/core/java/com/android/server/media/quality/MediaQualityUtils.java7
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java56
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java44
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java2
-rw-r--r--services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java2
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java2
-rw-r--r--services/core/java/com/android/server/power/ScreenUndimDetector.java44
-rw-r--r--services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java42
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java15
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java43
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java39
-rw-r--r--services/core/java/com/android/server/wm/ActivitySnapshotController.java8
-rw-r--r--services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java14
-rw-r--r--services/core/java/com/android/server/wm/AppCompatLetterboxUtils.java7
-rw-r--r--services/core/java/com/android/server/wm/AppCompatRoundedCorners.java2
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java1587
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java4
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java7
-rw-r--r--services/core/java/com/android/server/wm/BaseAppSnapshotPersister.java84
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java45
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java64
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowListenerController.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java9
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java1
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java23
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java22
-rw-r--r--services/core/java/com/android/server/wm/Task.java2
-rw-r--r--services/core/java/com/android/server/wm/ViewServer.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java200
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java24
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java50
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java8
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/java/com/android/server/flags.aconfig8
-rw-r--r--services/proguard.flags1
-rw-r--r--services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java9
-rw-r--r--services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/util/IgnoreableExpect.kt2
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java20
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt36
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java81
-rw-r--r--services/tests/media/mediarouterservicetest/Android.bp10
-rw-r--r--services/tests/media/mediarouterservicetest/AndroidTest.xml3
-rw-r--r--services/tests/media/mediarouterservicetest/src/com/android/server/media/MediaRouterMetricLoggerTest.java140
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java42
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java10
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java10
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp4
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java94
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilterTest.java79
-rw-r--r--services/tests/servicestests/src/com/android/server/appop/DiscreteAppOpXmlPersistenceTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/appop/DiscreteOpsMigrationAndRollbackTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java69
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java95
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxUtilsTest.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java26
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java27
-rw-r--r--services/usb/java/com/android/server/usb/UsbManagerInternal.java50
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java48
-rw-r--r--telecomm/java/android/telecom/Call.java28
-rw-r--r--telecomm/java/android/telecom/ParcelableCall.java32
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java2
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java55
-rw-r--r--tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java8
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bottom_half_pip.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bubble.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml3
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_launch_new.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml3
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml3
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent_launch.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/notification_button.xml2
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/task_button.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java2
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewActivity.java5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewTaskActivity.java5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NotificationActivity.java8
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java8
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitOnlyActivity.java5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java2
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ShowWhenLockedActivity.java5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SimpleActivity.java5
-rw-r--r--tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt8
-rw-r--r--tests/PackageWatchdog/Android.bp4
-rw-r--r--tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java67
-rw-r--r--tools/codegen/src/com/android/codegen/Debug.kt2
-rw-r--r--tools/codegen/src/com/android/codegen/FeatureFlag.kt4
-rw-r--r--tools/codegen/src/com/android/codegen/FileInfo.kt8
-rw-r--r--tools/codegen/src/com/android/codegen/Generators.kt4
-rw-r--r--tools/codegen/src/com/android/codegen/Utils.kt2
-rw-r--r--tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt18
1022 files changed, 28434 insertions, 13937 deletions
diff --git a/Android.bp b/Android.bp
index 303fa2cd18da..127556f8e075 100644
--- a/Android.bp
+++ b/Android.bp
@@ -103,10 +103,10 @@ filegroup {
":android.hardware.gnss-V2-java-source",
":android.hardware.graphics.common-V3-java-source",
":android.hardware.keymaster-V4-java-source",
- ":android.hardware.radio-V4-java-source",
- ":android.hardware.radio.data-V4-java-source",
- ":android.hardware.radio.network-V4-java-source",
- ":android.hardware.radio.voice-V4-java-source",
+ ":android.hardware.radio-V5-java-source",
+ ":android.hardware.radio.data-V5-java-source",
+ ":android.hardware.radio.network-V5-java-source",
+ ":android.hardware.radio.voice-V5-java-source",
":android.hardware.security.secureclock-V1-java-source",
":android.hardware.thermal-V3-java-source",
":android.hardware.tv.tuner-V3-java-source",
@@ -232,13 +232,13 @@ java_library {
"android.hardware.gnss-V2.1-java",
"android.hardware.health-V1.0-java-constants",
"android.hardware.radio-V1.6-java",
- "android.hardware.radio.data-V4-java",
- "android.hardware.radio.ims-V3-java",
- "android.hardware.radio.messaging-V4-java",
- "android.hardware.radio.modem-V4-java",
- "android.hardware.radio.network-V4-java",
- "android.hardware.radio.sim-V4-java",
- "android.hardware.radio.voice-V4-java",
+ "android.hardware.radio.data-V5-java",
+ "android.hardware.radio.ims-V4-java",
+ "android.hardware.radio.messaging-V5-java",
+ "android.hardware.radio.modem-V5-java",
+ "android.hardware.radio.network-V5-java",
+ "android.hardware.radio.sim-V5-java",
+ "android.hardware.radio.voice-V5-java",
"android.hardware.thermal-V1.0-java-constants",
"android.hardware.thermal-V1.0-java",
"android.hardware.thermal-V1.1-java",
@@ -415,6 +415,7 @@ java_defaults {
"mimemap",
"av-types-aidl-java",
"tv_tuner_resource_manager_aidl_interface-java",
+ "media_quality_aidl_interface-java",
"soundtrigger_middleware-aidl-java",
"modules-utils-binary-xml",
"modules-utils-build",
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index abec170f3b7d..d52bbc245157 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -18,6 +18,7 @@ package com.android.server.job.controllers;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+import android.annotation.NonNull;
import android.app.job.JobInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -28,6 +29,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Log;
@@ -56,7 +58,10 @@ public final class DeviceIdleJobsController extends StateController {
private static final boolean DEBUG = JobSchedulerService.DEBUG
|| Log.isLoggable(TAG, Log.DEBUG);
- private static final long BACKGROUND_JOBS_DELAY = 3000;
+ /** Prefix to use with all constant keys in order to "sub-namespace" the keys. */
+ private static final String DIJC_CONSTANT_PREFIX = "dijc_";
+ private static final String KEY_BACKGROUND_JOBS_DELAY_MS =
+ DIJC_CONSTANT_PREFIX + "background_jobs_delay_ms";
static final int PROCESS_BACKGROUND_JOBS = 1;
@@ -78,6 +83,8 @@ public final class DeviceIdleJobsController extends StateController {
private int[] mDeviceIdleWhitelistAppIds;
private int[] mPowerSaveTempWhitelistAppIds;
+ private long mBackgroundJobsDelay;
+
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -128,6 +135,9 @@ public final class DeviceIdleJobsController extends StateController {
public DeviceIdleJobsController(JobSchedulerService service) {
super(service);
+ mBackgroundJobsDelay = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_jobSchedulerBackgroundJobsDelay);
+
mHandler = new DeviceIdleJobsDelayHandler(AppSchedulingModuleThread.get().getLooper());
// Register for device idle mode changes
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -165,7 +175,7 @@ public final class DeviceIdleJobsController extends StateController {
// When coming out of doze, process all foreground uids and EJs immediately,
// while others will be processed after a delay of 3 seconds.
mService.getJobStore().forEachJob(mShouldRushEvaluation, mDeviceIdleUpdateFunctor);
- mHandler.sendEmptyMessageDelayed(PROCESS_BACKGROUND_JOBS, BACKGROUND_JOBS_DELAY);
+ mHandler.sendEmptyMessageDelayed(PROCESS_BACKGROUND_JOBS, mBackgroundJobsDelay);
}
}
// Inform the job scheduler service about idle mode changes
@@ -237,6 +247,26 @@ public final class DeviceIdleJobsController extends StateController {
}
@Override
+ public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
+ @NonNull String key) {
+ switch (key) {
+ case KEY_BACKGROUND_JOBS_DELAY_MS:
+ mBackgroundJobsDelay = Math.max(0, properties.getLong(key, mBackgroundJobsDelay));
+ break;
+ }
+ }
+
+ @Override
+ public void dumpConstants(IndentingPrintWriter pw) {
+ pw.println();
+ pw.print(DeviceIdleJobsController.class.getSimpleName());
+ pw.println(":");
+ pw.increaseIndent();
+ pw.print(KEY_BACKGROUND_JOBS_DELAY_MS, mBackgroundJobsDelay).println();
+ pw.decreaseIndent();
+ }
+
+ @Override
public void dumpControllerStateLocked(final IndentingPrintWriter pw,
final Predicate<JobStatus> predicate) {
pw.println("Idle mode: " + mDeviceIdleMode);
diff --git a/core/api/current.txt b/core/api/current.txt
index 3da5a5cca861..7bc0fb220e1a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -56108,6 +56108,17 @@ package android.view {
method @NonNull public android.view.WindowInsets getWindowInsets();
}
+ @FlaggedApi("android.xr.xr_manifest_entries") public final class XrWindowProperties {
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String PROPERTY_XR_ACTIVITY_START_MODE = "android.window.PROPERTY_XR_ACTIVITY_START_MODE";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED = "android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED = "XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED = "XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_ACTIVITY_START_MODE_HOME_SPACE = "XR_ACTIVITY_START_MODE_HOME_SPACE";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_ACTIVITY_START_MODE_UNDEFINED = "XR_ACTIVITY_START_MODE_UNDEFINED";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_BOUNDARY_TYPE_LARGE = "XR_BOUNDARY_TYPE_LARGE";
+ field @FlaggedApi("android.xr.xr_manifest_entries") public static final String XR_BOUNDARY_TYPE_NO_RECOMMENDATION = "XR_BOUNDARY_TYPE_NO_RECOMMENDATION";
+ }
+
}
package android.view.accessibility {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 00ec48b79541..d651010b641a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3031,6 +3031,7 @@ package android.provider {
field public static final String DISABLED_PRINT_SERVICES = "disabled_print_services";
field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages";
field public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
+ field public static final String GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled";
field public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";
field public static final String NOTIFICATION_BADGING = "notification_badging";
field public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b4f653354e07..d5df48a2ea22 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -10060,9 +10060,11 @@ public class Activity extends ContextThemeWrapper
}
});
if (mJankTracker == null) {
- // TODO b/377960907 use the Choreographer attached to the ViewRootImpl instead.
- mJankTracker = new JankTracker(Choreographer.getInstance(),
- decorView);
+ if (android.app.jank.Flags.viewrootChoreographer()) {
+ mJankTracker = new JankTracker(decorView);
+ } else {
+ mJankTracker = new JankTracker(Choreographer.getInstance(), decorView);
+ }
}
// TODO b/377674765 confirm this is the string we want logged.
mJankTracker.setActivityName(getComponentName().getClassName());
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ef757d532648..127a08b04e87 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3266,7 +3266,6 @@ public class Notification implements Parcelable
final Class<? extends Style> notificationStyle = getNotificationStyle();
return notificationStyle == null
- || BigPictureStyle.class.equals(notificationStyle)
|| BigTextStyle.class.equals(notificationStyle)
|| CallStyle.class.equals(notificationStyle)
|| ProgressStyle.class.equals(notificationStyle);
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index cb2b8adae0f9..8a8877f441a9 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -558,6 +558,11 @@ public final class DeviceAdminInfo implements Parcelable {
}
public void dump(Printer pw, String prefix) {
+ pw.println("mVisible: " + mVisible);
+ pw.println("mUsesPolicies: " + mUsesPolicies);
+ pw.println("mSupportsTransferOwnership: " + mSupportsTransferOwnership);
+ pw.println("mHeadlessDeviceOwnerMode: " + mHeadlessDeviceOwnerMode);
+
pw.println(prefix + "Receiver:");
mActivityInfo.dump(pw, prefix + " ");
}
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index 9c85b09f6be3..e3f67811757c 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -25,6 +25,7 @@ import android.view.AttachedSurfaceControl;
import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.View;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import com.android.internal.annotations.VisibleForTesting;
@@ -100,7 +101,7 @@ public class JankTracker {
public void run() {
mDecorView.getViewTreeObserver()
.removeOnWindowAttachListener(mOnWindowAttachListener);
- registerForJankData();
+ initializeJankTrackingComponents();
}
}, REGISTRATION_DELAY_MS);
}
@@ -115,6 +116,7 @@ public class JankTracker {
}
};
+ // TODO remove this once the viewroot_choreographer bugfix has been rolled out. b/399724640
public JankTracker(Choreographer choreographer, View decorView) {
mStateTracker = new StateTracker(choreographer);
mJankDataProcessor = new JankDataProcessor(mStateTracker);
@@ -124,6 +126,19 @@ public class JankTracker {
}
/**
+ * Using this constructor delays the instantiation of the StateTracker and JankDataProcessor
+ * until after the OnWindowAttachListener is fired and the instance of Choreographer attached to
+ * the ViewRootImpl can be passed to StateTracker. This should ensures the vsync ids we are
+ * using to keep track of active states line up with the ids that are being returned by
+ * OnJankDataListener.
+ */
+ public JankTracker(View decorView) {
+ mDecorView = decorView;
+ mHandlerThread.start();
+ registerWindowListeners();
+ }
+
+ /**
* Merges app jank stats reported by components outside the platform to the current pending
* stats
*/
@@ -131,6 +146,9 @@ public class JankTracker {
getHandler().post(new Runnable() {
@Override
public void run() {
+ if (mJankDataProcessor == null) {
+ return;
+ }
mJankDataProcessor.mergeJankStats(appJankStats, mActivityName);
}
});
@@ -192,8 +210,7 @@ public class JankTracker {
public void enableAppJankTracking() {
// Add the activity as a state, this will ensure we track frames to the activity without the
// need for a decorated widget to be used.
- // TODO b/376116199 replace "NONE" with UNSPECIFIED once the API changes are merged.
- mStateTracker.putState("NONE", mActivityName, "NONE");
+ addActivityToStateTracking();
mTrackingEnabled = true;
registerForJankData();
}
@@ -203,27 +220,33 @@ public class JankTracker {
*/
public void disableAppJankTracking() {
mTrackingEnabled = false;
- // TODO b/376116199 replace "NONE" with UNSPECIFIED once the API changes are merged.
- mStateTracker.removeState("NONE", mActivityName, "NONE");
+ removeActivityFromStateTracking();
unregisterForJankData();
}
/**
- * Retrieve all pending widget states, this is intended for testing purposes only.
+ * Retrieve all pending widget states, this is intended for testing purposes only. If
+ * this is called before StateTracker has been created the method will just return without
+ * copying any data to the stateDataList parameter.
*
* @param stateDataList the ArrayList that will be populated with the pending states.
*/
@VisibleForTesting
public void getAllUiStates(@NonNull ArrayList<StateTracker.StateData> stateDataList) {
+ if (mStateTracker == null) return;
mStateTracker.retrieveAllStates(stateDataList);
}
/**
* Retrieve all pending jank stats before they are logged, this is intended for testing
- * purposes only.
+ * purposes only. If this method is called before JankDataProcessor is created it will return
+ * an empty HashMap.
*/
@VisibleForTesting
public HashMap<String, JankDataProcessor.PendingJankStat> getPendingJankStats() {
+ if (mJankDataProcessor == null) {
+ return new HashMap<>();
+ }
return mJankDataProcessor.getPendingJankStats();
}
@@ -233,8 +256,10 @@ public class JankTracker {
*/
@VisibleForTesting
public void forceListenerRegistration() {
+ addActivityToStateTracking();
mSurfaceControl = mDecorView.getRootSurfaceControl();
registerJankDataListener();
+ mListenersRegistered = true;
}
private void unregisterForJankData() {
@@ -270,6 +295,10 @@ public class JankTracker {
*/
@VisibleForTesting
public boolean shouldTrack() {
+ if (DEBUG) {
+ Log.d(DEBUG_KEY, String.format("mTrackingEnabled: %s | mListenersRegistered: %s",
+ mTrackingEnabled, mListenersRegistered));
+ }
return mTrackingEnabled && mListenersRegistered;
}
@@ -313,4 +342,36 @@ public class JankTracker {
}
return mHandler;
}
+
+ private void addActivityToStateTracking() {
+ if (mStateTracker == null) return;
+
+ mStateTracker.putState(AppJankStats.WIDGET_CATEGORY_UNSPECIFIED, mActivityName,
+ AppJankStats.WIDGET_STATE_UNSPECIFIED);
+ }
+
+ private void removeActivityFromStateTracking() {
+ if (mStateTracker == null) return;
+
+ mStateTracker.removeState(AppJankStats.WIDGET_CATEGORY_UNSPECIFIED, mActivityName,
+ AppJankStats.WIDGET_STATE_UNSPECIFIED);
+ }
+
+ private void initializeJankTrackingComponents() {
+ ViewRootImpl viewRoot = mDecorView.getViewRootImpl();
+ if (viewRoot == null || viewRoot.getChoreographer() == null) {
+ return;
+ }
+
+ if (mStateTracker == null) {
+ mStateTracker = new StateTracker(viewRoot.getChoreographer());
+ }
+
+ if (mJankDataProcessor == null) {
+ mJankDataProcessor = new JankDataProcessor(mStateTracker);
+ }
+
+ addActivityToStateTracking();
+ registerForJankData();
+ }
}
diff --git a/core/java/android/app/jank/flags.aconfig b/core/java/android/app/jank/flags.aconfig
index a62df1b3cbf7..de98b88d2aca 100644
--- a/core/java/android/app/jank/flags.aconfig
+++ b/core/java/android/app/jank/flags.aconfig
@@ -14,4 +14,14 @@ flag {
namespace: "system_performance"
description: "Controls whether the system will log frame metrics related to app jank"
bug: "366265225"
+}
+
+flag {
+ name: "viewroot_choreographer"
+ namespace: "system_performance"
+ description: "when enabled janktracker will get the instance of choreographer from viewrootimpl"
+ bug: "377960907"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 8e6b88c66408..5c267c9f6475 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -255,6 +255,16 @@ flag {
}
flag {
+ name: "redaction_on_lockscreen_metrics"
+ namespace: "systemui"
+ description: "enables metrics when redacting notifications on the lockscreen"
+ bug: "343631648"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "api_rich_ongoing"
is_exported: true
namespace: "systemui"
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 0085e4f42397..4fb3982c3754 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -150,3 +150,11 @@ flag {
description: "Settings override for virtual devices"
bug: "371801645"
}
+
+flag {
+ namespace: "virtual_devices"
+ name: "viewconfiguration_apis"
+ description: "APIs for settings ViewConfiguration attributes on virtual devices"
+ bug: "370720522"
+ is_exported: true
+}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 5c904c15e706..7f4fd3eff57e 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -617,8 +617,8 @@ flag {
}
flag {
- namespace: "multi_user"
name: "logout_user_api"
+ namespace: "multiuser"
description: "Add API to logout user"
bug: "350045389"
}
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 343e4b5668c0..0c8a9ed56ae8 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -476,6 +476,16 @@ public abstract class DisplayManagerInternal {
public abstract boolean isDisplayReadyForMirroring(int displayId);
/**
+ * Called by {@link com.android.server.wm.WindowManagerService} to notify whether a display
+ * should be in the topology.
+ * @param displayId The logical ID of the display
+ * @param inTopology Whether the display should be in the topology. This being true does not
+ * guarantee that the display will be in the topology - Display Manager might
+ * also check other parameters.
+ */
+ public abstract void onDisplayBelongToTopologyChanged(int displayId, boolean inTopology);
+
+ /**
* Called by {@link com.android.server.display.DisplayBackupHelper} when backup files were
* restored and are ready to be reloaded.
*/
diff --git a/core/java/android/hardware/usb/IUsbManagerInternal.aidl b/core/java/android/hardware/usb/IUsbManagerInternal.aidl
new file mode 100644
index 000000000000..32479d449f24
--- /dev/null
+++ b/core/java/android/hardware/usb/IUsbManagerInternal.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+import android.hardware.usb.IUsbOperationInternal;
+
+/** @hide */
+interface IUsbManagerInternal {
+
+ /* Disable/enable USB data on a port for System Service callers. */
+ boolean enableUsbDataSignal(boolean enable, int disableReason);
+}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 7b47efd47008..894b068b1528 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -527,22 +527,13 @@ public class InputMethodService extends AbstractInputMethodService {
public static final int IME_ACTIVE = 1 << 0;
/**
- * The IME is perceptibly visible to the user.
+ * The IME is visible.
*
* @hide
*/
public static final int IME_VISIBLE = 1 << 1;
/**
- * The IME is visible, but not yet perceptible to the user (e.g. fading in)
- * by {@link android.view.WindowInsetsController}.
- *
- * @see InputMethodManager#reportPerceptible
- * @hide
- */
- public static final int IME_VISIBLE_IMPERCEPTIBLE = 1 << 2;
-
- /**
* The IME window visibility state.
*
* @hide
@@ -550,7 +541,6 @@ public class InputMethodService extends AbstractInputMethodService {
@IntDef(flag = true, prefix = { "IME_" }, value = {
IME_ACTIVE,
IME_VISIBLE,
- IME_VISIBLE_IMPERCEPTIBLE,
})
public @interface ImeWindowVisibility {}
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 0964cde5a1f4..c3ec96d17437 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -145,8 +145,17 @@ public final class MessageQueue {
}
if (Flags.forceConcurrentMessageQueue()) {
- sIsProcessAllowedToUseConcurrent = true;
- return;
+ // b/379472827: Robolectric tests use reflection to access MessageQueue.mMessages.
+ // This is a hack to allow Robolectric tests to use the legacy implementation.
+ try {
+ Class.forName("org.robolectric.Robolectric");
+ } catch (ClassNotFoundException e) {
+ // This is not a Robolectric test.
+ sIsProcessAllowedToUseConcurrent = true;
+ return;
+ }
+ // This is a Robolectric test.
+ // Continue to the following checks.
}
final String processName = Process.myProcessName();
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index 3aad0fd7b82f..70a17ab00235 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -87,8 +87,12 @@ public class ExternalVibration implements Parcelable {
int capturePreset = in.readInt();
int flags = in.readInt();
AudioAttributes.Builder builder = new AudioAttributes.Builder();
- return builder.setUsage(usage)
- .setContentType(contentType)
+ if (AudioAttributes.isSystemUsage(usage)) {
+ builder.setSystemUsage(usage);
+ } else {
+ builder.setUsage(usage);
+ }
+ return builder.setContentType(contentType)
.setCapturePreset(capturePreset)
.setFlags(flags)
.build();
@@ -196,7 +200,9 @@ public class ExternalVibration implements Parcelable {
}
private static void writeAudioAttributes(AudioAttributes attrs, Parcel out) {
- out.writeInt(attrs.getUsage());
+ // Since we allow audio system usages, must use getSystemUsage() instead of getUsage() for
+ // all usages.
+ out.writeInt(attrs.getSystemUsage());
out.writeInt(attrs.getContentType());
out.writeInt(attrs.getCapturePreset());
out.writeInt(attrs.getAllFlags());
diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java
index a8a22f675e08..b82f278ef7d5 100644
--- a/core/java/android/os/health/SystemHealthManager.java
+++ b/core/java/android/os/health/SystemHealthManager.java
@@ -216,7 +216,7 @@ public class SystemHealthManager {
/**
* Gets the maximum number of TIDs this device supports for getting CPU headroom.
* <p>
- * See {@link CpuHeadroomParams#setTids(int...)}.
+ * See {@link CpuHeadroomParams.Builder#setTids(int...)}.
*
* @return the maximum size of TIDs supported
* @throws UnsupportedOperationException if the CPU headroom API is unsupported.
@@ -288,9 +288,7 @@ public class SystemHealthManager {
/**
* Gets the range of the calculation window size for CPU headroom.
* <p>
- * In API version 36, the range will be a superset of [50, 10000].
- * <p>
- * See {@link CpuHeadroomParams#setCalculationWindowMillis(int)}.
+ * See {@link CpuHeadroomParams.Builder#setCalculationWindowMillis(int)}.
*
* @return the range of the calculation window size supported in milliseconds.
* @throws UnsupportedOperationException if the CPU headroom API is unsupported.
@@ -310,9 +308,7 @@ public class SystemHealthManager {
/**
* Gets the range of the calculation window size for GPU headroom.
* <p>
- * In API version 36, the range will be a superset of [50, 10000].
- * <p>
- * See {@link GpuHeadroomParams#setCalculationWindowMillis(int)}.
+ * See {@link GpuHeadroomParams.Builder#setCalculationWindowMillis(int)}.
*
* @return the range of the calculation window size supported in milliseconds.
* @throws UnsupportedOperationException if the GPU headroom API is unsupported.
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 0476f62ec263..4bd54a173601 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -71,6 +71,19 @@ flag {
}
flag {
+ name: "unknown_call_setting_blocked_logging_enabled"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "permissions"
+ description: "enable the metrics when blocking certain app installs during an unknown call"
+ bug: "364535720"
+
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "op_enable_mobile_data_by_user"
is_exported: true
namespace: "permissions"
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 60e57b588be0..f91056dbce30 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8651,6 +8651,34 @@ public final class Settings {
public static final String DOCKED_CLOCK_FACE = "docked_clock_face";
/**
+ * Setting to indicate that content filters should be enabled on web browsers.
+ *
+ * <ul>
+ * <li>0 = Allow all sites
+ * <li>1 = Try to block explicit sites
+ * </ul>
+ *
+ * @hide
+ */
+ @Readable
+ public static final String BROWSER_CONTENT_FILTERS_ENABLED =
+ "browser_content_filters_enabled";
+
+ /**
+ * Setting to indicate that content filters should be enabled in web search engines.
+ *
+ * <ul>
+ * <li>0 = Off
+ * <li>1 = Filter
+ * </ul>
+ *
+ * @hide
+ */
+ @Readable
+ public static final String SEARCH_CONTENT_FILTERS_ENABLED =
+ "search_content_filters_enabled";
+
+ /**
* Set by the system to track if the user needs to see the call to action for
* the lockscreen notification policy.
* @hide
@@ -10583,6 +10611,9 @@ public final class Settings {
*
* @hide
*/
+ @TestApi
+ @Readable
+ @SuppressLint({"UnflaggedApi", "NoSettingsProvider"}) // @TestApi purely for CTS support.
public static final String GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled";
/**
@@ -11129,6 +11160,12 @@ public final class Settings {
public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake";
/**
+ * Controls whether double tap to sleep is enabled.
+ * @hide
+ */
+ public static final String DOUBLE_TAP_TO_SLEEP = "double_tap_to_sleep";
+
+ /**
* The current assistant component. It could be a voice interaction service,
* or an activity that handles ACTION_ASSIST, or empty which means using the default
* handling.
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index f7f4eeca58e2..7d7087642fad 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4988,6 +4988,66 @@ public final class Telephony {
public static final String COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM =
"is_satellite_provisioned_for_non_ip_datagram";
+ /**
+ * TelephonyProvider column name for satellite entitlement barred plmns list separated by
+ * comma [,]. The value of this column is set based on entitlement query result for
+ * satellite configuration. Ex : 31026,302820,40445
+ * By default, it's empty.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ENTITLEMENT_BARRED_PLMNS =
+ "satellite_entitlement_barred_plmns";
+
+
+ /**
+ * TelephonyProvider column name for satellite entitlement data plan for plmns which is
+ * built in Json format in Key:Value pair. The value of this column is set based on
+ * entitlement query result for satellite configuration.
+ * Ex : {"302820":0,"31026":1, "40445":0}
+ * By default, it's empty.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS =
+ "satellite_entitlement_data_plan_plmns";
+
+ /**
+ * TelephonyProvider column name for satellite entitlement service type map which is
+ * built in Json format in Key:Value pair. The value of this column is set based on
+ * entitlement query result for satellite configuration.
+ * Ex : {"302820":[1,3],"31026":[2,3],"40445":[1,3]}
+ * By default, it's empty.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP =
+ "satellite_entitlement_service_type_map";
+
+ /**
+ * TelephonyProvider column name for satellite entitlement data service policy type map
+ * which is built in Json format in Key:Value pair. The value of this column is set based
+ * on entitlement query result for satellite configuration.
+ * Ex : {"302820":2, "31026":1}
+ * By default, it's empty.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY =
+ "satellite_entitlement_data_service_policy";
+
+ /**
+ * TelephonyProvider column name for satellite entitlement voice service policy type map
+ * which is built in Json format in Key:Value pair. The value of this column is set
+ * based on entitlement query result for satellite configuration.
+ * Ex : {"302820":2, "31026":1}.
+ * By default, it's empty.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY =
+ "satellite_entitlement_voice_service_policy";
+
/** All columns in {@link SimInfo} table. */
private static final List<String> ALL_COLUMNS = List.of(
COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
@@ -5065,7 +5125,12 @@ public final class Telephony {
COLUMN_SATELLITE_ENTITLEMENT_STATUS,
COLUMN_SATELLITE_ENTITLEMENT_PLMNS,
COLUMN_SATELLITE_ESOS_SUPPORTED,
- COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM
+ COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM,
+ COLUMN_SATELLITE_ENTITLEMENT_BARRED_PLMNS,
+ COLUMN_SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS,
+ COLUMN_SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP,
+ COLUMN_SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY,
+ COLUMN_SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY
);
/**
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 770e234381c4..0b2239aa42b2 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -57,6 +57,7 @@ import java.util.concurrent.Executor;
@SystemService(Context.ADVANCED_PROTECTION_SERVICE)
public final class AdvancedProtectionManager {
private static final String TAG = "AdvancedProtectionMgr";
+ private static final String PKG_SETTINGS = "com.android.settings";
//TODO(b/378931989): Switch to android.app.admin.DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY
//when the appropriate flag is launched.
@@ -343,6 +344,7 @@ public final class AdvancedProtectionManager {
}
Intent intent = new Intent(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG);
+ intent.setPackage(PKG_SETTINGS);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_SUPPORT_DIALOG_FEATURE, featureId);
intent.putExtra(EXTRA_SUPPORT_DIALOG_TYPE, type);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9d0773f0a606..7dc96f21b5ae 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1836,6 +1836,7 @@ public final class ViewRootImpl implements ViewParent,
eventsToBeRegistered,
mBasePackageName);
+ // LINT.IfChange(fi_cb)
if (forceInvertColor()) {
if (mForceInvertObserver == null) {
mForceInvertObserver = new ContentObserver(mHandler) {
@@ -1844,7 +1845,6 @@ public final class ViewRootImpl implements ViewParent,
updateForceDarkMode();
}
};
-
final Uri[] urisToObserve = {
Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED),
@@ -1859,6 +1859,7 @@ public final class ViewRootImpl implements ViewParent,
}
}
}
+ // LINT.ThenChange(/services/core/java/com/android/server/UiModeManagerService.java:fi_cb)
}
/**
@@ -13654,4 +13655,11 @@ public final class ViewRootImpl implements ViewParent,
ThreadedRenderer.preInitBufferAllocator();
}
}
+
+ /**
+ * @hide
+ */
+ public Choreographer getChoreographer() {
+ return mChoreographer;
+ }
}
diff --git a/core/java/android/view/XrWindowProperties.java b/core/java/android/view/XrWindowProperties.java
new file mode 100644
index 000000000000..23021a563393
--- /dev/null
+++ b/core/java/android/view/XrWindowProperties.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.FlaggedApi;
+
+/**
+ * Class for XR-specific window properties to put in application manifests.
+ */
+@FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+public final class XrWindowProperties {
+ /** @hide */
+ private XrWindowProperties() {}
+
+ /**
+ * Both Application and activity level
+ * {@link android.content.pm.PackageManager.Property PackageManager.Property} for an app to
+ * inform the system of the activity launch mode in XR. When it is declared at the application
+ * level, all activities are set to the defined value, unless it is overridden at the activity
+ * level.
+ *
+ * <p>The default value is {@link #XR_ACTIVITY_START_MODE_UNDEFINED}.
+ *
+ * <p>The available values are:
+ * <ul>
+ * <li>{@link #XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED}
+ * <li>{@link #XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED}
+ * <li>{@link #XR_ACTIVITY_START_MODE_HOME_SPACE}
+ * <li>{@link #XR_ACTIVITY_START_MODE_UNDEFINED}
+ * </ul>
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * &lt;application&gt;
+ * &lt;property
+ * android:name="android.window.PROPERTY_ACTIVITY_XR_START_MODE"
+ * android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED|
+ * XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED|
+ * XR_ACTIVITY_START_MODE_HOME_SPACE|
+ * XR_ACTIVITY_START_MODE_UNDEFINED"/&gt;
+ * &lt;/application&gt;
+ * </pre>
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String PROPERTY_XR_ACTIVITY_START_MODE =
+ "android.window.PROPERTY_XR_ACTIVITY_START_MODE";
+
+ /**
+ * Defines the value to launch an activity in unmanaged full space mode in XR, where the
+ * activity itself is rendering the space and controls its own scene graph. This should be used
+ * for all activities that use OpenXR to render.
+ *
+ * @see #PROPERTY_XR_ACTIVITY_START_MODE
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED =
+ "XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED";
+
+ /**
+ * The default value if not specified. If used, the actual launching mode will be determined by
+ * the system based on the launching activity's current mode and the launching flags. When
+ * {@link #PROPERTY_XR_ACTIVITY_START_MODE} is used at the application level, apps can use this
+ * value to reset at individual activity level.
+ *
+ * @see #PROPERTY_XR_ACTIVITY_START_MODE
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_ACTIVITY_START_MODE_UNDEFINED =
+ "XR_ACTIVITY_START_MODE_UNDEFINED";
+
+ /**
+ * Defines the value to launch an activity in
+ * <a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/transition-home-space-to-full-space">managed
+ * full space mode</a> in XR, where the system is rendering the activity from a scene graph.
+ *
+ * @see #PROPERTY_XR_ACTIVITY_START_MODE
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED =
+ "XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED";
+
+ /**
+ * Defines the value to launch an activity in
+ * <a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/transition-home-space-to-full-space">home
+ * space mode</a> in XR.
+ *
+ * @see #PROPERTY_XR_ACTIVITY_START_MODE
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_ACTIVITY_START_MODE_HOME_SPACE =
+ "XR_ACTIVITY_START_MODE_HOME_SPACE";
+
+ /**
+ * Both Application and activity level
+ * {@link android.content.pm.PackageManager.Property PackageManager.Property} for an app to
+ * inform the system of the type of safety boundary recommended for the activity. When it is
+ * declared at the application level, all activities are set to the defined value, unless it is
+ * overridden at the activity level. When not declared, the system will not enforce any
+ * recommendations for a type of safety boundary and will continue to use the type that is
+ * currently in use.
+ *
+ * <p>The default value is {@link #XR_BOUNDARY_TYPE_NO_RECOMMENDATION}.
+ *
+ * <p>The available values are:
+ * <ul>
+ * <li>{@link #XR_BOUNDARY_TYPE_LARGE}
+ * <li>{@link #XR_BOUNDARY_TYPE_NO_RECOMMENDATION}
+ * </ul>
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * &lt;application&gt;
+ * &lt;property
+ * android:name="android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED"
+ * android:value="XR_BOUNDARY_TYPE_LARGE|
+ * XR_BOUNDARY_TYPE_NO_RECOMMENDATION"/&gt;
+ * &lt;/application&gt;
+ * </pre>
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED =
+ "android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED";
+
+ /**
+ * Defines the value to launch an activity with no recommendations for the type of safety
+ * boundary. The system will continue to use the type of safety boundary that is currently
+ * in use.
+ *
+ * @see #PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_BOUNDARY_TYPE_NO_RECOMMENDATION =
+ "XR_BOUNDARY_TYPE_NO_RECOMMENDATION";
+
+ /**
+ * Defines the value to launch an activity with a large boundary recommended. This is useful for
+ * activities which expect users to be moving around. The system will ask the user to use a
+ * larger size for their safety boundary and check that their space is clear, if the larger
+ * size is not already in use. This larger size will be determined by the system.
+ *
+ * @see #PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED
+ */
+ @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
+ public static final String XR_BOUNDARY_TYPE_LARGE = "XR_BOUNDARY_TYPE_LARGE";
+}
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index 00c702036124..17165cdcf7b1 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -94,6 +94,7 @@ public enum DesktopModeFlags {
ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES(
Flags::enableDesktopWindowingMultiInstanceFeatures, true),
ENABLE_DESKTOP_WINDOWING_PERSISTENCE(Flags::enableDesktopWindowingPersistence, true),
+ ENABLE_DESKTOP_WINDOWING_PIP(Flags::enableDesktopWindowingPip, false),
ENABLE_DESKTOP_WINDOWING_QUICK_SWITCH(Flags::enableDesktopWindowingQuickSwitch, true),
ENABLE_DESKTOP_WINDOWING_SCVH_CACHE(Flags::enableDesktopWindowingScvhCacheBugFix, true),
ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
@@ -108,6 +109,7 @@ public enum DesktopModeFlags {
ENABLE_FULLY_IMMERSIVE_IN_DESKTOP(Flags::enableFullyImmersiveInDesktop, true),
ENABLE_HANDLE_INPUT_FIX(Flags::enableHandleInputFix, true),
ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
+ ENABLE_INPUT_LAYER_TRANSITION_FIX(Flags::enableInputLayerTransitionFix, false),
ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, false),
ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS(
@@ -136,10 +138,14 @@ public enum DesktopModeFlags {
ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
Flags::enableWindowingTransitionHandlersObservers, false),
EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, false),
+ FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK(
+ Flags::forceCloseTopTransparentFullscreenTask, false),
IGNORE_ASPECT_RATIO_RESTRICTIONS_FOR_RESIZEABLE_FREEFORM_ACTIVITIES(
Flags::ignoreAspectRatioRestrictionsForResizeableFreeformActivities, true),
INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC(
- Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true)
+ Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true),
+ INHERIT_TASK_BOUNDS_FOR_TRAMPOLINE_TASK_LAUNCHES(
+ Flags::inheritTaskBoundsForTrampolineTaskLaunches, false),
// go/keep-sorted end
;
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 403577a266d2..ce3a101a7519 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -27,6 +27,17 @@ flag {
}
flag {
+ name: "inherit_task_bounds_for_trampoline_task_launches"
+ namespace: "lse_desktop_experience"
+ description: "Forces trampoline task launches to inherit the bounds of the previous instance /n"
+ "before is closes to prevent each task from cascading."
+ bug: "392815318"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "include_top_transparent_fullscreen_task_in_desktop_heuristic"
namespace: "lse_desktop_experience"
description: "Whether to include any top transparent fullscreen task launched in desktop /n"
@@ -50,6 +61,17 @@ flag {
}
flag {
+ name: "force_close_top_transparent_fullscreen_task"
+ namespace: "lse_desktop_experience"
+ description: "If a top transparent fullscreen task is on top of desktop mode, force it to /n"
+ "close if another task is opened or brought to front."
+ bug: "395041610"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_windowing_dynamic_initial_bounds"
namespace: "lse_desktop_experience"
description: "Enables new initial bounds for desktop windowing which adjust depending on app constraints"
@@ -154,6 +176,16 @@ flag {
}
flag {
+ name: "enable_input_layer_transition_fix"
+ namespace: "lse_desktop_experience"
+ description: "Enables a bugfix for input layer disposal during certain transitions."
+ bug: "371473978"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_accessible_custom_headers"
namespace: "lse_desktop_experience"
description: "Enables a11y-friendly custom header input handling"
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index f2ba16cf43d6..3927c713e500 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -51,6 +51,17 @@ flag {
}
flag {
+ name: "use_cached_insets_for_display_switch"
+ namespace: "windowing_frontend"
+ description: "Reduce intermediate insets changes for display switch"
+ bug: "266197298"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "edge_to_edge_by_default"
namespace: "windowing_frontend"
description: "Make app go edge-to-edge by default when targeting SDK 35 or greater"
@@ -75,6 +86,14 @@ flag {
}
flag {
+ name: "action_mode_edge_to_edge"
+ namespace: "windowing_frontend"
+ description: "Make contextual action bar edge-to-edge"
+ bug: "379783298"
+ is_fixed_read_only: true
+}
+
+flag {
name: "keyguard_going_away_timeout"
namespace: "windowing_frontend"
description: "Allow a maximum of 10 seconds with keyguardGoingAway=true before force-resetting"
@@ -490,6 +509,17 @@ flag {
description: "Sets Launch powermode for activity launches earlier"
bug: "399380676"
is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "scramble_snapshot_file_name"
+ namespace: "windowing_frontend"
+ description: "Scramble the file name of task snapshot."
+ bug: "293139053"
+ is_fixed_read_only: true
metadata {
purpose: PURPOSE_BUGFIX
}
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index f2efa200918c..cbeaeda65fca 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -81,6 +81,16 @@ flag {
flag {
namespace: "windowing_sdk"
+ name: "activity_embedding_delay_task_fragment_finish_for_activity_launch"
+ description: "Fixes a race condition that we finish the TaskFragment too early when there is a pending activity launch."
+ bug: "390452023"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ namespace: "windowing_sdk"
name: "wlinfo_oncreate"
description: "Makes WindowLayoutInfo accessible without racing in the Activity#onCreate()"
bug: "337820752"
@@ -127,17 +137,6 @@ flag {
flag {
namespace: "windowing_sdk"
- name: "use_self_sync_transaction_for_layer"
- description: "Always use this.getSyncTransaction for assignLayer"
- bug: "388127825"
- is_fixed_read_only: true
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "windowing_sdk"
name: "safe_region_letterboxing"
description: "Enables letterboxing for a safe region"
bug: "380132497"
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 81ca23173457..c6207f9451c2 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -45,11 +45,13 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -203,15 +205,6 @@ public class BatteryStatsHistory {
BatteryHistoryFragment getLatestFragment();
/**
- * Given a fragment, returns the earliest fragment that follows it whose monotonic
- * start time falls within the specified range. `startTimeMs` is inclusive, `endTimeMs`
- * is exclusive.
- */
- @Nullable
- BatteryHistoryFragment getNextFragment(BatteryHistoryFragment current, long startTimeMs,
- long endTimeMs);
-
- /**
* Acquires a lock on the entire store.
*/
void lock();
@@ -268,6 +261,60 @@ public class BatteryStatsHistory {
void reset();
}
+ class BatteryHistoryParcelContainer {
+ private boolean mParcelReadyForReading;
+ private Parcel mParcel;
+ private BatteryStatsHistory.BatteryHistoryFragment mFragment;
+ private long mMonotonicStartTime;
+
+ BatteryHistoryParcelContainer(@NonNull Parcel parcel, long monotonicStartTime) {
+ mParcel = parcel;
+ mMonotonicStartTime = monotonicStartTime;
+ mParcelReadyForReading = true;
+ }
+
+ BatteryHistoryParcelContainer(@NonNull BatteryHistoryFragment fragment) {
+ mFragment = fragment;
+ mMonotonicStartTime = fragment.monotonicTimeMs;
+ mParcelReadyForReading = false;
+ }
+
+ @Nullable
+ Parcel getParcel() {
+ if (mParcelReadyForReading) {
+ return mParcel;
+ }
+
+ Parcel parcel = Parcel.obtain();
+ if (readFragmentToParcel(parcel, mFragment)) {
+ parcel.readInt(); // skip buffer size
+ mParcel = parcel;
+ } else {
+ parcel.recycle();
+ }
+ mParcelReadyForReading = true;
+ return mParcel;
+ }
+
+ long getMonotonicStartTime() {
+ return mMonotonicStartTime;
+ }
+
+ /**
+ * Recycles the parcel (if appropriate). Should be called after the parcel has been
+ * processed by the iterator.
+ */
+ void close() {
+ if (mParcel != null && mFragment != null) {
+ mParcel.recycle();
+ }
+ // ParcelContainers are not meant to be reusable. To prevent any unintentional
+ // access to the parcel after it has been recycled, clear the references to it.
+ mParcel = null;
+ mFragment = null;
+ }
+ }
+
private final Parcel mHistoryBuffer;
private final HistoryStepDetailsCalculator mStepDetailsCalculator;
private final Clock mClock;
@@ -447,6 +494,7 @@ public class BatteryStatsHistory {
mWritableHistory = writableHistory;
if (mWritableHistory != null) {
mMutable = false;
+ mHistoryBufferStartTime = mWritableHistory.mHistoryBufferStartTime;
mHistoryMonotonicEndTime = mWritableHistory.mHistoryMonotonicEndTime;
}
@@ -689,95 +737,66 @@ public class BatteryStatsHistory {
}
/**
- * When iterating history files and history buffer, always start from the lowest numbered
- * history file, when reached the mActiveFile (highest numbered history file), do not read from
- * mActiveFile, read from history buffer instead because the buffer has more updated data.
- *
- * @return The parcel that has next record. null if finished all history files and history
- * buffer
+ * Returns all chunks of accumulated history that contain items within the range between
+ * `startTimeMs` (inclusive) and `endTimeMs` (exclusive)
*/
- @Nullable
- public Parcel getNextParcel(long startTimeMs, long endTimeMs) {
- checkImmutable();
+ Queue<BatteryHistoryParcelContainer> getParcelContainers(long startTimeMs, long endTimeMs) {
+ if (mMutable) {
+ throw new IllegalStateException("Iterating over a mutable battery history");
+ }
- // First iterate through all records in current parcel.
- if (mCurrentParcel != null) {
- if (mCurrentParcel.dataPosition() < mCurrentParcelEnd) {
- // There are more records in current parcel.
- return mCurrentParcel;
- } else if (mHistoryBuffer == mCurrentParcel) {
- // finished iterate through all history files and history buffer.
- return null;
- } else if (mHistoryParcels == null
- || !mHistoryParcels.contains(mCurrentParcel)) {
- // current parcel is from history file.
- mCurrentParcel.recycle();
- }
+ if (endTimeMs == MonotonicClock.UNDEFINED || endTimeMs == 0) {
+ endTimeMs = Long.MAX_VALUE;
}
+ Queue<BatteryHistoryParcelContainer> containers = new ArrayDeque<>();
+
if (mStore != null) {
- BatteryHistoryFragment next = mStore.getNextFragment(mCurrentFragment, startTimeMs,
- endTimeMs);
- while (next != null) {
- mCurrentParcel = null;
- mCurrentParcelEnd = 0;
- final Parcel p = Parcel.obtain();
- if (readFragmentToParcel(p, next)) {
- int bufSize = p.readInt();
- int curPos = p.dataPosition();
- mCurrentParcelEnd = curPos + bufSize;
- mCurrentParcel = p;
- if (curPos < mCurrentParcelEnd) {
- mCurrentFragment = next;
- return mCurrentParcel;
- }
- } else {
- p.recycle();
+ List<BatteryHistoryFragment> fragments = mStore.getFragments();
+ for (int i = 0; i < fragments.size(); i++) {
+ BatteryHistoryFragment fragment = fragments.get(i);
+ if (fragment.monotonicTimeMs >= endTimeMs) {
+ break;
+ }
+
+ if (fragment.monotonicTimeMs >= startTimeMs && fragment != mActiveFragment) {
+ containers.add(new BatteryHistoryParcelContainer(fragment));
}
- next = mStore.getNextFragment(next, startTimeMs, endTimeMs);
}
}
- // mHistoryParcels is created when BatteryStatsImpl object is created from deserialization
- // of a parcel, such as Settings app or checkin file.
if (mHistoryParcels != null) {
- while (mParcelIndex < mHistoryParcels.size()) {
- final Parcel p = mHistoryParcels.get(mParcelIndex++);
+ for (int i = 0; i < mHistoryParcels.size(); i++) {
+ final Parcel p = mHistoryParcels.get(i);
if (!verifyVersion(p)) {
continue;
}
- // skip monotonic time field.
- p.readLong();
- // skip monotonic end time field
- p.readLong();
+
+ long monotonicStartTime = p.readLong();
+ if (monotonicStartTime >= endTimeMs) {
+ continue;
+ }
+
+ long monotonicEndTime = p.readLong();
+ if (monotonicEndTime < startTimeMs) {
+ continue;
+ }
+
// skip monotonic size field
p.readLong();
+ // skip buffer size field
+ p.readInt();
- final int bufSize = p.readInt();
- final int curPos = p.dataPosition();
- mCurrentParcelEnd = curPos + bufSize;
- mCurrentParcel = p;
- if (curPos < mCurrentParcelEnd) {
- return mCurrentParcel;
- }
+ containers.add(new BatteryHistoryParcelContainer(p, monotonicStartTime));
}
}
- // finished iterator through history files (except the last one), now history buffer.
- if (mHistoryBuffer.dataSize() <= 0) {
- // buffer is empty.
- return null;
- }
- mHistoryBuffer.setDataPosition(0);
- mCurrentParcel = mHistoryBuffer;
- mCurrentParcelEnd = mCurrentParcel.dataSize();
- return mCurrentParcel;
- }
-
- private void checkImmutable() {
- if (mMutable) {
- throw new IllegalStateException("Iterating over a mutable battery history");
+ if (mHistoryBufferStartTime < endTimeMs) {
+ mHistoryBuffer.setDataPosition(0);
+ containers.add(
+ new BatteryHistoryParcelContainer(mHistoryBuffer, mHistoryBufferStartTime));
}
+ return containers;
}
/**
@@ -818,21 +837,6 @@ public class BatteryStatsHistory {
}
/**
- * Extracts the monotonic time, as per {@link MonotonicClock}, from the supplied battery history
- * buffer.
- */
- public long getHistoryBufferStartTime(Parcel p) {
- int pos = p.dataPosition();
- p.setDataPosition(0);
- p.readInt(); // Skip the version field
- long monotonicTime = p.readLong();
- p.readLong(); // Skip monotonic end time field
- p.readLong(); // Skip monotonic size field
- p.setDataPosition(pos);
- return monotonicTime;
- }
-
- /**
* Writes the battery history contents for persistence.
*/
public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
diff --git a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
index 38398b4bf6f0..09f9b0bf8c7e 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
@@ -24,6 +24,7 @@ import android.util.Slog;
import android.util.SparseArray;
import java.util.Iterator;
+import java.util.Queue;
/**
* An iterator for {@link BatteryStats.HistoryItem}'s.
@@ -48,7 +49,10 @@ public class BatteryStatsHistoryIterator implements Iterator<BatteryStats.Histor
private long mBaseMonotonicTime;
private long mBaseTimeUtc;
private int mItemIndex = 0;
- private int mMaxHistoryItems;
+ private final int mMaxHistoryItems;
+ private int mParcelDataPosition;
+
+ private Queue<BatteryStatsHistory.BatteryHistoryParcelContainer> mParcelContainers;
public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, long startTimeMs,
long endTimeMs) {
@@ -62,7 +66,11 @@ public class BatteryStatsHistoryIterator implements Iterator<BatteryStats.Histor
@Override
public boolean hasNext() {
if (!mNextItemReady) {
- advance();
+ if (!advance()) {
+ mHistoryItem = null;
+ close();
+ }
+ mNextItemReady = true;
}
return mHistoryItem != null;
@@ -75,35 +83,48 @@ public class BatteryStatsHistoryIterator implements Iterator<BatteryStats.Histor
@Override
public BatteryStats.HistoryItem next() {
if (!mNextItemReady) {
- advance();
+ if (!advance()) {
+ mHistoryItem = null;
+ close();
+ }
}
mNextItemReady = false;
return mHistoryItem;
}
- private void advance() {
- while (true) {
- if (mItemIndex > mMaxHistoryItems) {
- Slog.wtfStack(TAG, "Number of battery history items is too large: " + mItemIndex);
- break;
- }
+ private boolean advance() {
+ if (mParcelContainers == null) {
+ mParcelContainers = mBatteryStatsHistory.getParcelContainers(mStartTimeMs, mEndTimeMs);
+ }
- Parcel p = mBatteryStatsHistory.getNextParcel(mStartTimeMs, mEndTimeMs);
- if (p == null) {
- break;
+ BatteryStatsHistory.BatteryHistoryParcelContainer container;
+ while ((container = mParcelContainers.peek()) != null) {
+ Parcel p = container.getParcel();
+ if (p == null || p.dataPosition() >= p.dataSize()) {
+ container.close();
+ mParcelContainers.remove();
+ mParcelDataPosition = 0;
+ continue;
}
if (!mTimeInitialized) {
- mBaseMonotonicTime = mBatteryStatsHistory.getHistoryBufferStartTime(p);
+ mBaseMonotonicTime = container.getMonotonicStartTime();
mHistoryItem.time = mBaseMonotonicTime;
mTimeInitialized = true;
}
try {
readHistoryDelta(p, mHistoryItem);
+ int dataPosition = p.dataPosition();
+ if (dataPosition <= mParcelDataPosition) {
+ Slog.wtf(TAG, "Corrupted battery history, parcel is not progressing: "
+ + dataPosition + " of " + p.dataSize());
+ return false;
+ }
+ mParcelDataPosition = dataPosition;
} catch (Throwable t) {
Slog.wtf(TAG, "Corrupted battery history", t);
- break;
+ return false;
}
if (mHistoryItem.cmd == BatteryStats.HistoryItem.CMD_CURRENT_TIME
@@ -111,21 +132,24 @@ public class BatteryStatsHistoryIterator implements Iterator<BatteryStats.Histor
mBaseTimeUtc = mHistoryItem.currentTime - (mHistoryItem.time - mBaseMonotonicTime);
}
- mHistoryItem.currentTime = mBaseTimeUtc + (mHistoryItem.time - mBaseMonotonicTime);
+ if (mHistoryItem.time < mStartTimeMs) {
+ continue;
+ }
- if (mEndTimeMs != 0 && mHistoryItem.time >= mEndTimeMs) {
- break;
+ if (mEndTimeMs != 0 && mEndTimeMs != MonotonicClock.UNDEFINED
+ && mHistoryItem.time >= mEndTimeMs) {
+ return false;
}
- if (mHistoryItem.time >= mStartTimeMs) {
- mItemIndex++;
- mNextItemReady = true;
- return;
+
+ if (mItemIndex++ > mMaxHistoryItems) {
+ Slog.wtfStack(TAG, "Number of battery history items is too large: " + mItemIndex);
+ return false;
}
- }
- mHistoryItem = null;
- mNextItemReady = true;
- close();
+ mHistoryItem.currentTime = mBaseTimeUtc + (mHistoryItem.time - mBaseMonotonicTime);
+ return true;
+ }
+ return false;
}
private void readHistoryDelta(Parcel src, BatteryStats.HistoryItem cur) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index e20a52b24485..3d81e4fc7acd 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -120,6 +120,7 @@ import com.android.internal.view.menu.MenuHelper;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.BackgroundFallback;
import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
+import com.android.window.flags.Flags;
import java.util.List;
import java.util.concurrent.Executor;
@@ -1003,7 +1004,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
public void onWindowSystemUiVisibilityChanged(int visible) {
updateColorViews(null /* insets */, true /* animate */);
- if (mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
+ if (!Flags.actionModeEdgeToEdge()
+ && mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
updateStatusGuardColor();
}
}
@@ -1040,7 +1042,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
mFrameOffsets.set(insets.getSystemWindowInsetsAsRect());
insets = updateColorViews(insets, true /* animate */);
- insets = updateStatusGuard(insets);
+ insets = updateActionModeInsets(insets);
if (getForeground() != null) {
drawableChanged();
}
@@ -1592,7 +1594,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
}
- private WindowInsets updateStatusGuard(WindowInsets insets) {
+ private WindowInsets updateActionModeInsets(WindowInsets insets) {
boolean showStatusGuard = false;
// Show the status guard when the non-overlay contextual action bar is showing
if (mPrimaryActionModeView != null) {
@@ -1608,54 +1610,78 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
final Rect rect = mTempRect;
// Apply the insets that have not been applied by the contentParent yet.
- WindowInsets innerInsets =
+ final WindowInsets innerInsets =
mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
- int newTopMargin = innerInsets.getSystemWindowInsetTop();
- int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
- int newRightMargin = innerInsets.getSystemWindowInsetRight();
-
- // Must use root window insets for the guard, because the color views consume
- // the navigation bar inset if the window does not request LAYOUT_HIDE_NAV - but
- // the status guard is attached at the root.
- WindowInsets rootInsets = getRootWindowInsets();
- int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
- int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
-
- if (mlp.topMargin != newTopMargin || mlp.leftMargin != newLeftMargin
- || mlp.rightMargin != newRightMargin) {
- mlpChanged = true;
- mlp.topMargin = newTopMargin;
- mlp.leftMargin = newLeftMargin;
- mlp.rightMargin = newRightMargin;
- }
+ final boolean consumesSystemWindowInsetsTop;
+ if (Flags.actionModeEdgeToEdge()) {
+ final Insets newPadding = innerInsets.getSystemWindowInsets();
+ final Insets newMargin = innerInsets.getInsets(
+ WindowInsets.Type.navigationBars());
+
+ // Don't extend into navigation bar area so the width can align with status
+ // bar color view.
+ if (mlp.leftMargin != newMargin.left
+ || mlp.rightMargin != newMargin.right) {
+ mlpChanged = true;
+ mlp.leftMargin = newMargin.left;
+ mlp.rightMargin = newMargin.right;
+ }
+
+ mPrimaryActionModeView.setPadding(
+ newPadding.left - newMargin.left,
+ newPadding.top,
+ newPadding.right - newMargin.right,
+ 0);
+ consumesSystemWindowInsetsTop = newPadding.top > 0;
+ } else {
+ int newTopMargin = innerInsets.getSystemWindowInsetTop();
+ int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
+ int newRightMargin = innerInsets.getSystemWindowInsetRight();
+
+ // Must use root window insets for the guard, because the color views
+ // consume the navigation bar inset if the window does not request
+ // LAYOUT_HIDE_NAV - but the status guard is attached at the root.
+ WindowInsets rootInsets = getRootWindowInsets();
+ int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
+ int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
+
+ if (mlp.topMargin != newTopMargin || mlp.leftMargin != newLeftMargin
+ || mlp.rightMargin != newRightMargin) {
+ mlpChanged = true;
+ mlp.topMargin = newTopMargin;
+ mlp.leftMargin = newLeftMargin;
+ mlp.rightMargin = newRightMargin;
+ }
- if (newTopMargin > 0 && mStatusGuard == null) {
- mStatusGuard = new View(mContext);
- mStatusGuard.setVisibility(GONE);
- final LayoutParams lp = new LayoutParams(MATCH_PARENT,
- mlp.topMargin, Gravity.LEFT | Gravity.TOP);
- lp.leftMargin = newGuardLeftMargin;
- lp.rightMargin = newGuardRightMargin;
- addView(mStatusGuard, indexOfChild(mStatusColorViewState.view), lp);
- } else if (mStatusGuard != null) {
- final LayoutParams lp = (LayoutParams)
- mStatusGuard.getLayoutParams();
- if (lp.height != mlp.topMargin || lp.leftMargin != newGuardLeftMargin
- || lp.rightMargin != newGuardRightMargin) {
- lp.height = mlp.topMargin;
+ if (newTopMargin > 0 && mStatusGuard == null) {
+ mStatusGuard = new View(mContext);
+ mStatusGuard.setVisibility(GONE);
+ final LayoutParams lp = new LayoutParams(MATCH_PARENT,
+ mlp.topMargin, Gravity.LEFT | Gravity.TOP);
lp.leftMargin = newGuardLeftMargin;
lp.rightMargin = newGuardRightMargin;
- mStatusGuard.setLayoutParams(lp);
+ addView(mStatusGuard, indexOfChild(mStatusColorViewState.view), lp);
+ } else if (mStatusGuard != null) {
+ final LayoutParams lp = (LayoutParams)
+ mStatusGuard.getLayoutParams();
+ if (lp.height != mlp.topMargin || lp.leftMargin != newGuardLeftMargin
+ || lp.rightMargin != newGuardRightMargin) {
+ lp.height = mlp.topMargin;
+ lp.leftMargin = newGuardLeftMargin;
+ lp.rightMargin = newGuardRightMargin;
+ mStatusGuard.setLayoutParams(lp);
+ }
}
- }
- // The action mode's theme may differ from the app, so
- // always show the status guard above it if we have one.
- showStatusGuard = mStatusGuard != null;
+ // The action mode's theme may differ from the app, so
+ // always show the status guard above it if we have one.
+ showStatusGuard = mStatusGuard != null;
- if (showStatusGuard && mStatusGuard.getVisibility() != VISIBLE) {
- // If it wasn't previously shown, the color may be stale
- updateStatusGuardColor();
+ if (showStatusGuard && mStatusGuard.getVisibility() != VISIBLE) {
+ // If it wasn't previously shown, the color may be stale
+ updateStatusGuardColor();
+ }
+ consumesSystemWindowInsetsTop = showStatusGuard;
}
// We only need to consume the insets if the action
@@ -1664,14 +1690,16 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
// screen_simple_overlay_action_mode.xml).
final boolean nonOverlay = (mWindow.getLocalFeaturesPrivate()
& (1 << Window.FEATURE_ACTION_MODE_OVERLAY)) == 0;
- if (nonOverlay && showStatusGuard) {
+ if (nonOverlay && consumesSystemWindowInsetsTop) {
insets = insets.inset(0, insets.getSystemWindowInsetTop(), 0, 0);
}
} else {
- // reset top margin
- if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
- mlpChanged = true;
- mlp.topMargin = 0;
+ if (!Flags.actionModeEdgeToEdge()) {
+ // reset top margin
+ if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
+ mlpChanged = true;
+ mlp.topMargin = 0;
+ }
}
}
if (mlpChanged) {
@@ -1679,7 +1707,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
}
}
- if (mStatusGuard != null) {
+ if (!Flags.actionModeEdgeToEdge() && mStatusGuard != null) {
mStatusGuard.setVisibility(showStatusGuard ? VISIBLE : GONE);
}
return insets;
@@ -2183,7 +2211,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
for (int i = getChildCount() - 1; i >= 0; i--) {
View v = getChildAt(i);
if (v != mStatusColorViewState.view && v != mNavigationColorViewState.view
- && v != mStatusGuard) {
+ && (Flags.actionModeEdgeToEdge() || v != mStatusGuard)) {
removeViewAt(i);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 80fc218839d5..d5bb51187ba4 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -34,6 +34,7 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
+import com.android.window.flags.Flags;
/**
* @hide
@@ -315,12 +316,14 @@ public class ActionBarContextView extends AbsActionBarView {
final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
- int maxHeight = mContentHeight > 0 ?
- mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
+ final int maxHeight = !Flags.actionModeEdgeToEdge() && mContentHeight > 0
+ ? mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
final int verticalPadding = getPaddingTop() + getPaddingBottom();
int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
- final int height = maxHeight - verticalPadding;
+ final int height = Flags.actionModeEdgeToEdge()
+ ? mContentHeight > 0 ? mContentHeight : maxHeight
+ : maxHeight - verticalPadding;
final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
if (mClose != null) {
@@ -376,7 +379,8 @@ public class ActionBarContextView extends AbsActionBarView {
}
setMeasuredDimension(contentWidth, measuredHeight);
} else {
- setMeasuredDimension(contentWidth, maxHeight);
+ setMeasuredDimension(contentWidth, Flags.actionModeEdgeToEdge()
+ ? mContentHeight + verticalPadding : maxHeight);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index ff57fd4fe2ce..362b79db4003 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -294,54 +294,24 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
}
}
- private boolean applyInsets(View view, Rect insets, boolean toPadding,
- boolean left, boolean top, boolean right, boolean bottom) {
- boolean changed;
- if (toPadding) {
- changed = setMargin(view, EMPTY_RECT, left, top, right, bottom);
- changed |= setPadding(view, insets, left, top, right, bottom);
- } else {
- changed = setPadding(view, EMPTY_RECT, left, top, right, bottom);
- changed |= setMargin(view, insets, left, top, right, bottom);
- }
- return changed;
- }
-
- private boolean setPadding(View view, Rect insets,
- boolean left, boolean top, boolean right, boolean bottom) {
- if ((left && view.getPaddingLeft() != insets.left)
- || (top && view.getPaddingTop() != insets.top)
- || (right && view.getPaddingRight() != insets.right)
- || (bottom && view.getPaddingBottom() != insets.bottom)) {
- view.setPadding(
- left ? insets.left : view.getPaddingLeft(),
- top ? insets.top : view.getPaddingTop(),
- right ? insets.right : view.getPaddingRight(),
- bottom ? insets.bottom : view.getPaddingBottom());
- return true;
- }
- return false;
- }
-
- private boolean setMargin(View view, Rect insets,
- boolean left, boolean top, boolean right, boolean bottom) {
+ private boolean setMargin(View view, int left, int top, int right, int bottom) {
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
boolean changed = false;
- if (left && lp.leftMargin != insets.left) {
+ if (lp.leftMargin != left) {
changed = true;
- lp.leftMargin = insets.left;
+ lp.leftMargin = left;
}
- if (top && lp.topMargin != insets.top) {
+ if (lp.topMargin != top) {
changed = true;
- lp.topMargin = insets.top;
+ lp.topMargin = top;
}
- if (right && lp.rightMargin != insets.right) {
+ if (lp.rightMargin != right) {
changed = true;
- lp.rightMargin = insets.right;
+ lp.rightMargin = right;
}
- if (bottom && lp.bottomMargin != insets.bottom) {
+ if (lp.bottomMargin != bottom) {
changed = true;
- lp.bottomMargin = insets.bottom;
+ lp.bottomMargin = bottom;
}
return changed;
}
@@ -367,12 +337,30 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
final Insets sysInsets = insets.getSystemWindowInsets();
mSystemInsets.set(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom);
- // The top and bottom action bars are always within the content area.
- boolean changed = applyInsets(mActionBarTop, mSystemInsets,
- mActionBarExtendsIntoSystemInsets, true, true, true, false);
- if (mActionBarBottom != null) {
- changed |= applyInsets(mActionBarBottom, mSystemInsets,
- mActionBarExtendsIntoSystemInsets, true, false, true, true);
+ boolean changed = false;
+ if (mActionBarExtendsIntoSystemInsets) {
+ // Don't extend into navigation bar area so the width can align with status bar
+ // color view.
+ final Insets navBarInsets = insets.getInsets(WindowInsets.Type.navigationBars());
+ final int paddingLeft = sysInsets.left - navBarInsets.left;
+ final int paddingRight = sysInsets.right - navBarInsets.right;
+ mActionBarTop.setPadding(paddingLeft, sysInsets.top, paddingRight, 0);
+ changed |= setMargin(
+ mActionBarTop, navBarInsets.left, 0, navBarInsets.right, 0);
+ if (mActionBarBottom != null) {
+ mActionBarBottom.setPadding(paddingLeft, 0, paddingRight, sysInsets.bottom);
+ changed |= setMargin(
+ mActionBarBottom, navBarInsets.left, 0, navBarInsets.right, 0);
+ }
+ } else {
+ mActionBarTop.setPadding(0, 0, 0, 0);
+ changed |= setMargin(
+ mActionBarTop, sysInsets.left, sysInsets.top, sysInsets.right, 0);
+ if (mActionBarBottom != null) {
+ mActionBarBottom.setPadding(0, 0, 0, 0);
+ changed |= setMargin(
+ mActionBarTop, sysInsets.left, 0, sysInsets.right, sysInsets.bottom);
+ }
}
// Cannot use the result of computeSystemWindowInsets, because that consumes the
@@ -521,7 +509,12 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
);
}
}
- setMargin(mContent, mContentInsets, true, true, true, true);
+ setMargin(
+ mContent,
+ mContentInsets.left,
+ mContentInsets.top,
+ mContentInsets.right,
+ mContentInsets.bottom);
if (!mLastInnerInsets.equals(mInnerInsets)) {
// If the inner insets have changed, we need to dispatch this down to
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 2cca3dbc4f2f..3da19220248b 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -1178,6 +1178,7 @@ public class ConversationLayout extends FrameLayout
}
newGroup.setShowingAvatar(!mIsOneToOne && !mIsCollapsed);
newGroup.setSingleLine(mIsCollapsed && TextUtils.isEmpty(mSummarizedContent));
+ newGroup.setIsCollapsed(mIsCollapsed);
newGroup.setSender(sender, nameOverride);
newGroup.setSending(groupIndex == (groups.size() - 1) && showSpinner);
mGroups.add(newGroup);
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index b31a200218ee..21bb7a9468bd 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -103,6 +103,7 @@ public class MessagingGroup extends NotificationOptimizedLinearLayout implements
private boolean mShowingAvatar = true;
private CharSequence mSenderName;
private boolean mSingleLine = false;
+ private boolean mIsCollapsed = false;
private LinearLayout mContentContainer;
private int mRequestedMaxDisplayedLines = Integer.MAX_VALUE;
private int mSenderTextPaddingSingleLine;
@@ -451,7 +452,7 @@ public class MessagingGroup extends NotificationOptimizedLinearLayout implements
private void updateIconVisibility() {
if (Flags.notificationsRedesignTemplates()) {
// We don't show any icon (other than the app or person icon) in the collapsed form.
- mMessagingIconContainer.setVisibility(mSingleLine ? GONE : VISIBLE);
+ mMessagingIconContainer.setVisibility(mIsCollapsed ? GONE : VISIBLE);
}
}
@@ -714,10 +715,18 @@ public class MessagingGroup extends NotificationOptimizedLinearLayout implements
updateMaxDisplayedLines();
updateClipRect();
updateSenderVisibility();
- updateIconVisibility();
}
}
+ /**
+ * Sets whether this is in a collapsed layout or not. Certain elements like icons are not shown
+ * when the notification is collapsed.
+ */
+ public void setIsCollapsed(boolean isCollapsed) {
+ mIsCollapsed = isCollapsed;
+ updateIconVisibility();
+ }
+
public boolean isSingleLine() {
return mSingleLine;
}
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 9fe2de82adee..4cc4b38f95a5 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -551,6 +551,7 @@ public class MessagingLayout extends FrameLayout
}
newGroup.setSingleLine(mIsCollapsed && TextUtils.isEmpty(mSummarizedContent));
newGroup.setShowingAvatar(!mIsCollapsed);
+ newGroup.setIsCollapsed(mIsCollapsed);
newGroup.setSender(sender, nameOverride);
newGroup.setSending(groupIndex == (groups.size() - 1) && showSpinner);
mGroups.add(newGroup);
diff --git a/core/java/com/android/internal/widget/PeopleHelper.java b/core/java/com/android/internal/widget/PeopleHelper.java
index 3f5b4a0d61fe..3aa4c8498747 100644
--- a/core/java/com/android/internal/widget/PeopleHelper.java
+++ b/core/java/com/android/internal/widget/PeopleHelper.java
@@ -110,7 +110,7 @@ public class PeopleHelper {
@NonNull
public Icon createAvatarSymbol(@NonNull CharSequence name, @NonNull String symbol,
@ColorInt int layoutColor) {
- if (symbol.isEmpty() || TextUtils.isDigitsOnly(symbol)
+ if (symbol == null || symbol.isEmpty() || TextUtils.isDigitsOnly(symbol)
|| SPECIAL_CHAR_PATTERN.matcher(symbol).find()) {
Icon avatarIcon = Icon.createWithResource(mContext, R.drawable.messaging_user);
avatarIcon.setTint(findColor(name, layoutColor));
diff --git a/core/jni/platform/host/HostRuntime.cpp b/core/jni/platform/host/HostRuntime.cpp
index 746740b0248b..1e8da730aff8 100644
--- a/core/jni/platform/host/HostRuntime.cpp
+++ b/core/jni/platform/host/HostRuntime.cpp
@@ -280,12 +280,18 @@ static string getJavaProperty(JNIEnv* env, const char* property_name,
return string(chars.c_str());
}
-static void loadIcuData(string icuPath) {
+static void loadIcuData(JNIEnv* env, string icuPath) {
void* addr = mmapFile(icuPath.c_str());
+ if (addr == nullptr) {
+ jniThrowRuntimeException(env, "Failed to map the ICU data file.");
+ }
UErrorCode err = U_ZERO_ERROR;
udata_setCommonData(addr, &err);
if (err != U_ZERO_ERROR) {
- ALOGE("Unable to load ICU data\n");
+ jniThrowRuntimeException(env,
+ format("udata_setCommonData failed with error code {}",
+ u_errorName(err))
+ .c_str());
}
}
@@ -296,12 +302,12 @@ static void loadIcuData() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
string icuPath = base::GetProperty("ro.icu.data.path", "");
if (!icuPath.empty()) {
- loadIcuData(icuPath);
+ loadIcuData(env, icuPath);
} else {
// fallback to read from java.lang.System.getProperty
string icuPathFromJava = getJavaProperty(env, "icu.data.path");
if (!icuPathFromJava.empty()) {
- loadIcuData(icuPathFromJava);
+ loadIcuData(env, icuPathFromJava);
}
}
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ae05666bc2a2..9967209c3f49 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Eenhandmodus"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra donker"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Gehoortoestelle"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Outoklik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ontkoppel"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Gekoppel"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktief"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vra ontsluitpatroon voordat jy ontspeld"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vra wagwoord voordat jy ontspeld"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Deur jou admin geïnstalleer.\nGaan na instellings om toegestaande toestemmings te sien"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Opgedateer deur jou administrateur"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte, sekere kenmerke en sommige netwerkverbindings af"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 19be04eabfbf..bdaf5a18a5ba 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"የአንድ እጅ ሁነታ"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ተጨማሪ ደብዛዛ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"የመስሚያ መሣሪያዎች"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ራስ-ሰር ጠቅ ማድረግ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ግንኙነት ተቋርጧል"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"ተገናኝቷል"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ገቢር"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ሥርዓተ-ጥለት ጠይቅ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"በአስተዳዳሪዎ ተጭኗል።\nየተፈቀዱ ፍቃዶችን ለማየት ወደ ቅንብሮች ይሂዱ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"በእርስዎ አስተዳዳሪ ተዘምኗል"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"እሺ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ባትሪ ቆጣቢ ጠቆር ያለ ገጽታን ያበራል እና የጀርባ እንቅስቃሴን፣ አንዳንድ ዕይታዊ ውጤቶችን፣ አንዳንድ ባህሪዎችን፣ እና አንዳንድ የአውታረ መረብ ግንኙነቶችን ይገድባል ወይም ያጠፋል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 66192cb01ebf..3b0e78dbada1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1807,8 +1807,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"وضع \"التصفح بيد واحدة\""</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"زيادة تعتيم الشاشة"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعات الأذن الطبية"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"النقر التلقائي"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"غير متّصل"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"متّصل"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"متّصل حاليًا"</string>
@@ -1970,7 +1969,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال نقش فتح القفل قبل إزالة التثبيت"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"تم التثبيت من قِبل المشرف.\nانتقِل إلى الإعدادات للاطّلاع على الأذونات الممنوحة"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"تم التحديث بواسطة المشرف"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"يؤدي استخدام ميزة \"توفير شحن البطارية\" إلى تفعيل وضع \"المظهر الداكن\" وتقييد أو إيقاف الأنشطة في الخلفية وبعض التأثيرات المرئية وميزات معيّنة وبعض اتصالات الشبكات."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index b85be47b4a38..5d93b655d741 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এখন হাতেৰে ব্যৱহাৰ কৰাৰ ম’ড"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিৰিক্তভাৱে পোহৰ কমোৱাৰ সুবিধা"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"শুনাৰ ডিভাইচ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"স্বয়ংক্ৰিয়ভাৱে ক্লিক কৰাৰ সুবিধা"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"সংযোগ বিচ্ছিন্ন হ’ল"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"সংযোগ কৰা হ’ল"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"সক্ৰিয় হৈ আছে"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"আপোনাৰ প্ৰশাসকে ইনষ্টল কৰিছে।\nপ্ৰদান কৰা অনুমতিসমূহ চাবলৈ ছেটিঙলৈ যাওক"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"আপোনাৰ প্ৰশাসকে আপেডট কৰিছে"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"আপোনাৰ প্ৰশাসকে মচিছে"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট, নিৰ্দিষ্ট কিছুমান সুবিধা আৰু নেটৱৰ্কৰ সংযোগ সীমিত অথবা অফ কৰে।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index b9bd5437c7b0..c6a0adea6d6f 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Birəlli rejim"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Əlavə tündləşmə"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eşitmə cihazları"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Avtomatik klikləmə"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Bağlantı kəsildi"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Qoşuldu"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivdir"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Qrafik açar istənilsin"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ayırmadan öncə parol istənilsin"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Admin quraşdırıb.\nVerilən icazələrə baxmaq üçün ayarlara keçin"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Admin tərəfindən yeniləndi"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Admin tərəfindən silindi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Enerjiyə Qənaət rejimi Tünd temanı aktivləşdirir, habelə arxa fon fəaliyyətini, bəzi vizual effektləri, müəyyən xüsusiyyətləri və bəzi şəbəkə bağlantılarını məhdudlaşdırır, yaxud söndürür."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a558de3d755a..2b4dc578e610 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1966,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 113be9de3185..8230b1c45757 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Рэжым кіравання адной рукой"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дадатковае памяншэнне яркасці"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слыхавыя апараты"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Аўтанацісканне"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Адключана"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Падключана"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Актыўная"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Усталявана адміністратарам.\nКаб паглядзець дадзеныя дазволы, перайдзіце ў налады"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Абноўлены вашым адміністратарам"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Выдалены вашым адміністратарам"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У рэжыме энергазберажэння ўключаецца цёмная тэма і выключаюцца ці абмяжоўваюцца дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты, пэўныя функцыі і падключэнні да сетак."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c36940f47371..1b0477f09538 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Работа с една ръка"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Допълнително затъмняване"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухови апарати"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автоматично кликване"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Няма връзка"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Свързано"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитване за фигура за отключване преди освобождаване"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитване за парола преди освобождаване"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирано от администратора ви.\nОтворете настройките, за да прегледате предоставените разрешения"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Актуализирано от администратора ви"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Изтрито от администратора ви"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Режимът за запазване на батерията включва тъмната тема и ограничава или изключва активността на заден план, някои визуални ефекти, определени функции и някои връзки с мрежата."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b79c1d703eb9..2461a70e1ab8 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এক হাতে ব্যবহার করার মোড"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম উজ্জ্বলতা"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"হিয়ারিং ডিভাইস"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"অটোক্লিক"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ডিসকানেক্ট হয়ে গেছে"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"কানেক্ট করা হয়েছে"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"অ্যাক্টিভ"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"আপনার অ্যাডমিন ইনস্টল করেছেন।\nঅনুমোদন করা অনুমতি দেখতে সেটিংসে যান"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"আপনার প্রশাসক আপডেট করেছেন"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"আপনার প্রশাসক মুছে দিয়েছেন"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ব্যাটারি সেভার ডার্ক থিম চালু করে এবং ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট, নির্দিষ্ট ফিচার ও কয়েকটি নেটওয়ার্ক কানেকশনের ব্যবহার সীমিত করে বা বন্ধ করে দেয়।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index a995746a28e3..b8d3283491c3 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjenje"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatski klik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nije povezano"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje prije poništavanja kačenja"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku prije nego se otkači"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je vaš administrator.\nIdite u postavke da pregledate data odobrenja"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je vaš administrator"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 62f59f2570f9..cbfa521c96e4 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode d\'una mà"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuació extra"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audiòfons"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automàtic"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconnectat"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connectat"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Actiu"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instal·lat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions de xarxa."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 5e7a8aa7ee2a..356cdc71b54a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jedné ruky"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé zobrazení"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Naslouchátka"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatické kliknutí"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Odpojeno"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Připojeno"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivní"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Nainstalováno administrátorem.\nUdělená oprávnění si můžete prohlédnout v nastavení."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizováno administrátorem"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Spořič baterie zapíná tmavý motiv a omezuje či vypíná aktivitu na pozadí, některé vizuální efekty, některé funkce a připojení k některým sítím."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ab7339491042..efe3e103d0e1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndstilstand"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dæmpet belysning"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoklik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ikke forbundet"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Forbundet"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installeret af din administrator.\nGå til Indstillinger for at se de tilladelser, der er blevet givet"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Opdateret af din administrator"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparefunktionen aktiverer Mørkt tema og begrænser eller deaktiverer aktivitet i baggrunden og visse visuelle effekter, funktioner og netværksforbindelser."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8bff3505e78b..fc0e9ed19b9d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhandmodus"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradunkel"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörgeräte"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatischer Klick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nicht verbunden"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Verbunden"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Von deinem Administrator installiert.\nRufe die Einstellungen auf, um gewährte Berechtigungen anzusehen."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Von deinem Administrator aktualisiert"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design. Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen werden eingeschränkt oder deaktiviert."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 0e968bd4da04..58f5d9db4d68 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Λειτουργία ενός χεριού"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Επιπλέον μείωση φωτεινότητας"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Συσκευές ακοής"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Αυτόματο κλικ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Αποσυνδέθηκε"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Συνδέθηκε"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Ενεργή"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Εγκαταστάθηκε από τον διαχειριστή σας.\nΜεταβείτε στις ρυθμίσεις για να δείτε τις άδειες που έχουν εκχωρηθεί"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ενημερώθηκε από τον διαχειριστή σας"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Διαγράφηκε από τον διαχειριστή σας"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Η Εξοικονόμηση μπαταρίας ενεργοποιεί το Σκούρο θέμα και περιορίζει ή απενεργοποιεί τη δραστηριότητα στο παρασκήνιο, ορισμένα οπτικά εφέ, συγκεκριμένες λειτουργίες και κάποιες συνδέσεις δικτύου."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 6c43f9a51dbd..320e63935fc9 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoclick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installed by your admin.\nGo to Settings to view granted permissions"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, certain features and some network connections."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 99abe8bfeb27..85471d8a5efb 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1965,7 +1965,7 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installed by your admin.\nGo to settings to view granted permissions"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
+ <string name="package_updated_device_owner" msgid="7770195449213776218">"Updated by your admin.\nGo to settings to view granted permissions"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, certain features, and some network connections."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 99040f3f56b9..730dd3b808e8 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoclick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installed by your admin.\nGo to Settings to view granted permissions"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, certain features and some network connections."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index cb1e92ed638f..a9654e525df4 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoclick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installed by your admin.\nGo to Settings to view granted permissions"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, certain features and some network connections."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 18cbfaa5b1dd..036ecfc59d87 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo de una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicitar desbloqueo para quitar fijación"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para quitar fijación"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Tu administrador realizó la instalación.\nVe a la configuración para ver los permisos otorgados"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Tu administrador actualizó este paquete"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Tu administrador borró este paquete"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"El Ahorro de batería activa el Tema oscuro y desactiva o restringe la actividad en segundo plano, algunos efectos visuales, algunas conexiones de red y otras funciones determinadas."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 852347388819..3553aea44c2d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo Una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audífonos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado por tu administrador.\nVe a Ajustes para ver los permisos concedidos."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado por el administrador"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a1ddf81c72a5..abecc1a76d3f 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ühekäerežiim"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Eriti tume"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuuldeseadmed"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automaatklikk"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ühendus katkestatud"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Ühendatud"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiivne"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installis teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Administraator on seda värskendanud"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akusäästja lülitab sisse tumeda teema ja lülitab välja taustategevused, mõned visuaalsed efektid, teatud funktsioonid ja võrguühendused või piirab neid."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index c63cfe666afe..64dc7303e8c1 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Esku bakarreko modua"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Are ilunago"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Entzumen-gailuak"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatikoki klik egiteko eginbidea"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Deskonektatuta"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Konektatuta"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktibo"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Administratzaileak instalatu du.\nEmandako baimenak ikusteko, joan ezarpenetara."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Administratzaileak eguneratu du"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratzaileak ezabatu du"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Bateria-aurreztaileak gai iluna aktibatzen du, eta atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk mugatzen edo desaktibatzen ditu."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5e1caad2cf2b..13083d0c04d4 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"حالت یک‌دستی"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"بسیار کم‌نور"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"دستگاه‌های کمک‌شنوایی"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"کلیک خودکار"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"متصل نیست"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"وصل شد"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"فعال"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبل‌از برداشتن سنجاق"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"سرپرست شما آن را نصب کرده است.\nبرای مشاهده اجازه‌های اعطاشده به تنظیمات بروید"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"توسط سرپرست سیستم به‌روزرسانی شد"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"توسط سرپرست سیستم حذف شد"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"تأیید"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"«بهینه‌سازی باتری» «زمینه تاریک» را روشن می‌کند و فعالیت پس‌زمینه، برخی از جلوه‌های بصری، ویژگی‌هایی خاص، و برخی از اتصال‌های شبکه را محدود یا خاموش می‌کند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f7115ebbffa3..145c5ee4bef1 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Yhden käden moodi"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Erittäin himmeä"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuulolaitteet"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automaattinen klikkaus"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Yhteys katkaistu"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Yhdistetty"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiivinen"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Järjestelmänvalvojan asentama.\nTarkista myönnetyt luvat asetuksista."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, tiettyjä ominaisuuksia sekä joitakin visuaalisia tehosteita ja verkkoyhteyksiä."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 56623a296c1c..0ee4112ed458 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode Une main"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Très sombre"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automatique"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Déconnecté"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connecté"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Actif"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAccédez aux paramètres pour consulter les autorisations accordées"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Mise à jour par votre administrateur"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Le mode Économiseur de pile active le thème sombre et limite ou désactive l\'activité en arrière-plan, certains effets visuels, certaines fonctionnalités et certaines connexions réseau."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 90a0f441d0c9..a5b6f9a92dce 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode une main"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminosité ultra-réduite"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automatique"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Déconnecté"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connecté"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Actif"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"L\'économiseur de batterie active le thème sombre et limite ou désactive l\'activité en arrière-plan ainsi que certains effets visuels, fonctionnalités et connexions réseau."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index a2b53818dec6..332387ad0131 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo dunha soa man"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pola persoa administradora.\nVai á configuración para ver os permisos concedidos"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado polo teu administrador"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado polo teu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Coa función Aforro de batería, actívase o tema escuro e restrínxense ou desactívanse a actividade en segundo plano, algúns efectos visuais e determinadas funcións e conexións de rede."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 9d57bde4ab4b..7a39d634508e 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1966,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"તમારા ઍડમિન દ્વારા ઇન્સ્ટૉલ કરવામાં આવ્યું છે.\nઆપેલી પરવાનગીઓ જોવા માટે સેટિંગ પર જાઓ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ કરવામાં આવેલ છે"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખવામાં આવેલ છે"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ઓકે"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"બૅટરી સેવર ઘેરી થીમની સુવિધા ચાલુ કરે છે અને બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ, અમુક સુવિધાઓ અને કેટલાક નેટવર્ક કનેક્શન મર્યાદિત કે બંધ કરે છે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 563b724292f4..2c43996064ea 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"वन-हैंडेड मोड"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"कान की मशीन"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"अपने-आप क्लिक होने की सुविधा"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिसकनेक्ट हो गया"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट हो गया"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"चालू है"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"इसे आपके एडमिन ने इंस्टॉल किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"आपके व्यवस्थापक ने अपडेट किया है"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"आपके व्यवस्थापक ने हटा दिया है"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ठीक है"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बैटरी सेवर, गहरे रंग वाली थीम को चालू करता है. साथ ही, इस मोड में बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और कुछ खास सुविधाएं कम या बंद हो जाती हैं. कुछ इंटरनेट कनेक्शन भी पूरी तरह काम नहीं करते."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index fec624d94edc..d870a1dbda61 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Još tamnije"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušna pomagala"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatski klik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nije povezano"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje radi otkvačivanja"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži zaporku radi otkvačivanja"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao vaš administrator.\nOtvorite postavke da biste pregledali dodijeljena dopuštenja"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao administrator"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"U redu"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 7871aba30258..350d51dee68c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Egykezes mód"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extrasötét"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hallásjavító eszközök"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatikus kattintás"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Leválasztva"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Csatlakozva"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktív"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Feloldási minta kérése a kitűzés feloldásához"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Jelszó kérése a rögzítés feloldásához"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"A rendszergazda által telepítve.\nLépjen a beállításokhoz a megadott engedélyek megtekintéséhez."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"A rendszergazda által frissítve"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"A rendszergazda által törölve"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Az Akkumulátorkímélő mód bekapcsolja a Sötét témát, és korlátozza vagy kikapcsolja a háttérbeli tevékenységeket, valamint bizonyos vizuális effekteket, funkciókat és hálózati kapcsolatokat."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 01e51106ea3d..655af9395fa3 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Մեկ ձեռքի ռեժիմ"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Հավելյալ խամրեցում"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Լսողական սարքեր"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Ավտոմատ սեղմում"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Անջատված է"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Միացված է"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Ակտիվ է"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Հարցնել ապակողպող նախշը"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Հարցնել գաղտնաբառը"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Տեղադրվել է ադմինիստրատորի կողմից։\nԱնցեք կարգավորումներ՝ տրամադրված թույլտվությունները դիտելու համար"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Թարմացվել է ձեր ադմինիստրատորի կողմից"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Ջնջվել է ձեր ադմինիստրատորի կողմից"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Եղավ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"«Մարտկոցի տնտեսում» գործառույթը միացնում է մուգ թեման և անջատում կամ սահմանափակում է աշխատանքը ֆոնային ռեժիմում, որոշ վիզուալ էֆեկտներ, ցանցային միացումներ և այլ գործառույթներ։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index df42e47e7028..305d23a15c00 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode satu tangan"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra redup"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Alat bantu dengar"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Klik otomatis"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Tidak terhubung"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Terhubung"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktif"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Meminta pola pembukaan kunci sebelum melepas sematan"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Meminta sandi sebelum melepas sematan"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Diinstal oleh admin Anda.\nBuka setelan untuk melihat izin yang diberikan"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Diupdate oleh admin Anda"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dihapus oleh admin Anda"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Oke"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penghemat Baterai akan mengaktifkan Tema gelap dan membatasi atau menonaktifkan aktivitas latar belakang, beberapa efek visual, fitur tertentu, dan beberapa koneksi jaringan."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 40d642d2fda4..cdf89ad4424d 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhent stilling"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mjög dökkt"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Heyrnartæki"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Sjálfvirkur smellur"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Aftengt"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Tengt"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Virkt"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Sett upp af stjórnanda.\nFarðu í stillingar til að sjá heimildir"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Kerfisstjóri uppfærði"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Kerfisstjóri eyddi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Rafhlöðusparnaður kveikir á dökku þema og takmarkar eða slekkur á bakgrunnsvirkni, sumum myndáhrifum, tilteknum eiginleikum og sumum nettengingum."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e501c572f94e..3b7d1ec750ee 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1966,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Richiedi sequenza di sblocco prima di sbloccare"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Richiedi password prima di sbloccare"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installato dall\'amministratore.\nVai alle impostazioni per visualizzare le autorizzazioni concesse"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Aggiornato dall\'amministratore"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminato dall\'amministratore"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Ok"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Il risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, nonché alcuni effetti visivi, funzionalità e connessioni di rete."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index c9984e21c95e..cf7374868a50 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1967,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"החבילה הותקנה על ידי האדמין.\nצריך לעבור להגדרות כדי לראות את ההרשאות שניתנו"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"עודכנה על ידי מנהל המערכת"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"נמחקה על ידי מנהל המערכת"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים, תכונות מסוימות וחלק מהחיבורים לרשתות."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 7ab896e6b247..f8bc2413fca0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"画面固定を解除する前にロック解除パターンの入力を求める"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"オフライン再生を解除する前にパスワードの入力を求める"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"管理者によりインストールされています。\n付与された権限を確認するには、設定に移動してください"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"管理者により更新されています"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"管理者により削除されています"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"バッテリー セーバーを ON にすると、ダークモードが ON になります。また、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 4d634d4fe752..8aa0af3efc44 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ცალი ხელის რეჟიმი"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"დამატებითი დაბინდვა"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"სმენის აპარატები"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ავტოდაწკაპუნება"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"კავშირი გაწყვეტილია"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"დაკავშირებული"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"აქტიური"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"დაინსტალირებულია თქვენი ადმინისტრატორის მიერ.\nდაშვებული ნებართვების სანახავად გადადით პარამეტრებზე"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"წაიშალა თქვენი ადმინისტრატორის მიერ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"კარგი"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ბატარეის დამზოგი ჩართავს მუქ თემას და შეზღუდავს ან გამორთავს ფონურ აქტივობას, ზოგიერთ ვიზუალურ ეფექტს, გარკვეულ ფუნქციებსა და ზოგიერთ ქსელთან კავშირს."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 8d54a32b625c..3908427d9f97 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бір қолмен басқару режимі"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Экранды қарайту"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Есту аппараттары"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автоматты басу"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ажыратылды"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Қосылды"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Белсенді"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Әкімшіңіз орнатты.\nБерілген рұқсаттарды көру үшін параметрлерге өтіңіз."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Әкімші жаңартқан"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Әкімші жойған"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнемдеу режимі қараңғы режимді іске қосады және фондық әрекеттерге, кейбір визуалдық әсерлерге, белгілі бір функциялар мен кейбір желі байланыстарына шектеу қояды немесе оларды өшіреді."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index d7e02997714b..dee23f65e8ca 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"មុខងារប្រើដៃម្ខាង"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ងងឹតខ្លាំង"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ចុចស្វ័យប្រវត្តិ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"បាន​ផ្ដាច់"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"បានភ្ជាប់"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"សកម្ម"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"សួរ​រក​លំនាំ​ដោះ​សោ​មុន​ពេលដោះខ្ទាស់"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"សួរ​រក​ពាក្យ​សម្ងាត់​មុន​ពេល​ផ្ដាច់"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក។\nចូលទៅកាន់ការកំណត់ ដើម្បីមើលការ​អនុញ្ញាតដែលផ្ដល់ឱ្យ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ធ្វើ​បច្ចុប្បន្នភាព​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"លុប​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"មុខងារ​សន្សំថ្មបើកទម្រង់រចនាងងឹត និងដាក់កំហិត ឬបិទសកម្មភាពផ្ទៃខាងក្រោយ បែបផែនរូបភាពមួយចំនួន មុខងារជាក់លាក់ និងការតភ្ជាប់បណ្ដាញមួយចំនួន។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 9771def44b23..c1a70b0f7276 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ಒಂದು ಕೈ ಮೋಡ್‌"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ಇನ್ನಷ್ಟು ಮಬ್ಬು"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ಆಟೋಕ್ಲಿಕ್"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ಸಕ್ರಿಯವಾಗಿದೆ"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್ ಕೇಳು"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ್ದಾರೆ.\nನೀಡಲಾದ ಅನುಮತಿಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಪ್‌ಡೇಟ್ ಮಾಡಲ್ಪಟ್ಟಿದೆ"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಳಿಸಿದ್ದಾರೆ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ಸರಿ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ಬ್ಯಾಟರಿ ಸೇವರ್, ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್‌ಗಳು, ಕೆಲವು ಫೀಚರ್‌ಗಳು ಮತ್ತು ಇತರ ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕಗಳನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಆಫ್ ಮಾಡುತ್ತದೆ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a39db4b07f3e..be4a28423a93 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"한 손 모드"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"더 어둡게"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"청각 보조 기기"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"자동 클릭"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"연결 끊김"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"연결됨"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"활성"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"관리자에 의해 설치되었습니다.\n부여된 권한을 확인하려면 설정으로 이동하세요."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"관리자에 의해 업데이트되었습니다."</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"관리자에 의해 삭제되었습니다."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"확인"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"절전 모드는 어두운 테마를 사용하고 백그라운드 활동, 일부 시각 효과, 특정 기능 및 일부 네트워크 연결을 제한하거나 사용 중지합니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index fbc3afdc573d..121908a416a4 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бир кол режими"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Кошумча караңгылатуу"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Угуу түзмөктөрү"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Авточыкылдатуу"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ажыратылды"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Туташты"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Жигердүү"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бошотуудан мурун графикалык ачкыч суралсын"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Бошотуудан мурун сырсөз суралсын"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Администраторуңуз орнотту.\nБерилген уруксаттарды көрүү үчүн параметрлерге өтүңүз"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнөмдөөчү режимде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер, белгилүү бир функциялар жана айрым тармакка туташуулар чектелип же өчүрүлөт."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index a0a6b38644ea..ad62671d5e5b 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ໂໝດມືດຽວ"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ຫຼຸດແສງເປັນພິເສດ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ອຸປະກອນຊ່ວຍຟັງ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ການຄລິກອັດຕະໂນມັດ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ນຳໃຊ້ຢູ່"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"​ຖາມ​ຫາ​ຮູບ​ແບບ​ປົດ​ລັອກ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"​ຖາມ​ຫາ​ລະ​ຫັດ​ຜ່ານ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ຕິດຕັ້ງໂດຍຜູ້ເບິ່ງແຍງຂອງທ່ານ.\nເຂົ້າໄປການຕັ້ງຄ່າເພື່ອເບິ່ງສິດທີ່ໄດ້ຮັບອະນຸຍາດ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ຖືກອັບໂຫລດໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ຖືກລຶບອອກໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ຕົກລົງ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດໃຊ້ຮູບແບບສີສັນມືດ ແລະ ຈຳກັດ ຫຼື ປິດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກທາງພາບຈຳນວນໜຶ່ງ, ຄຸນສົມບັດບາງຢ່າງ ແລະ ການເຊື່ອມຕໍ່ເຄືອຂ່າຍບາງອັນ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 0b4967a9ab92..27a08c25a84e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienos rankos režimas"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Itin blanku"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Klausos įrenginiai"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatinis paspaudimas"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Atjungta"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Prisijungta"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktyvus"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Prašyti atrakinimo piešinio prieš atsegant"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Prašyti slaptažodžio prieš atsegant"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Įdiegė administratorius.\nEikite į nustatymus ir peržiūrėkite suteiktus leidimus"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Atnaujino administratorius"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Ištrynė administratorius"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Gerai"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akumuliatoriaus tausojimo priemonė įjungia tamsiąją temą ir apriboja arba išjungia veiklą fone, kai kuriuos vaizdinius efektus, tam tikras funkcijas bei kai kuriuos tinklo ryšius."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 0d19dc26bb39..78c7ebdb4587 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienas rokas režīms"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dzirdes aparāti"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automātiskā klikšķināšana"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Atvienota"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Pievienota"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktīva"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalēja jūsu administrators.\nPārejiet uz iestatījumiem, lai skatītu piešķirtās atļaujas."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Atjaunināja administrators"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dzēsa administrators"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Labi"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akumulatora enerģijas taupīšanas režīmā tiek ieslēgts tumšais motīvs un tiek ierobežotas vai izslēgtas darbības fonā, daži vizuālie efekti, noteiktas funkcijas un noteikti tīkla savienojumi."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 9889ea9d622b..146de01e7951 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1531,7 +1531,7 @@
<string name="ext_media_status_unmounted" msgid="8145812017295835941">"Исфрлено"</string>
<string name="ext_media_status_checking" msgid="159013362442090347">"Се проверува..."</string>
<string name="ext_media_status_mounted" msgid="3459448555811203459">"Подготвено"</string>
- <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Само за читање"</string>
+ <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Само за преглед"</string>
<string name="ext_media_status_bad_removal" msgid="508448566481406245">"Отстранет небезбедно"</string>
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"Оштетено"</string>
<string name="ext_media_status_unsupported" msgid="5460509911660539317">"Неподдржано"</string>
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим со една рака"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнително затемнување"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни помагала"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автоматско кликнување"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Не е поврзано"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Поврзано"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирано од администраторот.\nОдете во „Поставки“ за да ги прегледате доделените дозволи"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирано од администраторот"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Во ред"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"„Штедачот на батерија“ вклучува „Темна тема“ и ограничува или исклучува активност во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ff07aa08194b..3bb425ec9351 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"അൺപിന്നിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടൂ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"അൺപിന്നിനുമുമ്പ് പാസ്‌വേഡ് ആവശ്യപ്പെടൂ"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"നിങ്ങളുടെ അഡ്‌മിൻ ഇൻസ്‌റ്റാൾ ചെയ്തത്.\nനൽകിയ അനുമതികൾ കാണാൻ ക്രമീകരണത്തിലേക്ക് പോകുക"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"നിങ്ങളുടെ അഡ്‌മിൻ അപ്‌ഡേറ്റ് ചെയ്യുന്നത്"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"നിങ്ങളുടെ അഡ്‌മിൻ ഇല്ലാതാക്കുന്നത്"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ശരി"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\'ബാറ്ററി സേവർ\' ഡാർക്ക് തീം ഓണാക്കുന്നു, ഒപ്പം പശ്ചാത്തല ആക്‌റ്റിവിറ്റിയും ചില വിഷ്വൽ ഇഫക്റ്റുകളും ചില ഫീച്ചറുകളും ചില നെറ്റ്‌വർക്ക് കണക്ഷനുകളും പരിമിതപ്പെടുത്തുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3a1e0a621508..1ad9685a23d1 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Нэг гарын горим"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Хэт бүүдгэр"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Сонсголын төхөөрөмжүүд"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автомат товшилт"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Салсан"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Холбогдсон"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Идэвхтэй"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Танай админ суулгасан.\nОлгосон зөвшөөрлүүдийг харахын тулд тохиргоо руу очно уу"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Таны админ шинэчилсэн"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Таны админ устгасан"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батарей хэмнэгч нь Бараан загварыг асааж, дэвсгэрийн үйл ажиллагаа, зарим визуал эффект, тодорхой онцлогууд болон зарим сүлжээний холболтыг хязгаарлах эсвэл унтраана."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index d79dc6d96a3b..82f217ff21b2 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एकहाती मोड"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"आणखी डिम"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्रे"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ऑटोक्लिक"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिस्कनेक्ट केले आहे"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट केले आहे"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"अ‍ॅक्टिव्ह"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्‍यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्‍यापूर्वी संकेतशब्दासाठी विचारा"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"तुमच्या ॲडमिनने इंस्टॉल केले आहे.\nदिलेल्या परवानग्या पाहण्यासाठी सेटिंग्जवर जा"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"आपल्या प्रशासकाने अपडेट केले"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"आपल्या प्रशासकाने हटवले"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ओके"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बॅटरी सेव्हर गडद थीम सुरू करते आणि बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट, ठरावीक वैशिष्ट्ये व काही नेटवर्क कनेक्शन मर्यादित किंवा बंद करते."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 76d402796e6f..bda439a187a2 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Minta corak buka kunci sebelum menyahsemat"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Minta kata laluan sebelum menyahsemat"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Dipasang oleh pentadbir anda.\nAkses tetapan untuk melihat kebenaran yang diberikan"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Dikemas kini oleh pentadbir anda"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penjimat Bateri menghidupkan tema Gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual, ciri tertentu dan sesetengah sambungan rangkaian."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index fc6df7ac899c..9a8041644d5f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"လက်တစ်ဖက်သုံးမုဒ်"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ပိုမှိန်ခြင်း"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"နားကြားကိရိယာ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"အော်တိုနှိပ်ခြင်း"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ချိတ်ဆက်မထားပါ"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"ချိတ်ဆက်ထားသည်"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"သုံးနေသည်"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ပင်မဖြုတ်မီ လော့ခ်ဖွင့်ပုံစံကို မေးရန်"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"သင့်စီမံခန့်ခွဲသူက ထည့်သွင်းထားသည်။\nပေးထားသည့် ခွင့်ပြုချက်များကို ကြည့်ရန် ဆက်တင်များသို့ သွားပါ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"သင်၏ စီမံခန့်ခွဲသူက အပ်ဒိတ်လုပ်ထားသည်"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"သင်၏ စီမံခန့်ခွဲသူက ဖျက်လိုက်ပါပြီ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ဖန်တီးပြသချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b8cc711fcf46..d8e785f742d5 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndsmodus"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dimmet"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoklikk"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Frakoblet"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Tilkoblet"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installert av administratoren din.\nGå til innstillingene for å se hvilke tillatelser som er gitt"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Oppdatert av administratoren din"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet av administratoren din"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparing slår på mørkt tema og begrenser eller slår av bakgrunnsaktivitet, enkelte visuelle effekter, noen funksjoner og noen nettverkstilkoblinger."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 59071826720d..88e93709453e 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एक हाते मोड"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"अझै मधुरो"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"हियरिङ डिभाइसहरू"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"अटोक्लिक"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिस्कनेक्ट गरिएको"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट गरिएको"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"सक्रिय"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"यो प्याकेज तपाईंका एड्मिनले इन्स्टल गर्नुभएको हो।\nप्रदान गरिएका अनुमतिसम्बन्धी जानकारी हेर्न सेटिङमा जानुहोस्"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"तपाईंका प्रशासकले अद्यावधिक गर्नुभएको"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"तपाईंका प्रशासकले मेट्नुभएको"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ब्याट्री सेभरले अँध्यारो थिम अन गर्छ र ब्याकग्राउन्डमा हुने क्रियाकलाप, केही भिजुअल इफेक्ट, निश्चित सुविधा र केही नेटवर्क कनेक्सनहरू अफ गर्छ वा सीमित रूपमा मात्र चल्न दिन्छ।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 98ce463186ba..a43c0c443c8c 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met 1 hand"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dimmen"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hoortoestellen"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatisch klikken"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Verbinding verbroken"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Verbonden"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Actief"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ontgrendelingspatroon vragen om app los te maken"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vraag wachtwoord voor losmaken"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Geïnstalleerd door je beheerder.\nGa naar instellingen om verleende rechten te bekijken."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Geüpdatet door je beheerder"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4931bd2e90bf..f61e10919209 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ଲକ୍‌ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ପାସ୍‌ୱର୍ଡ ପଚାରନ୍ତୁ"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଇନଷ୍ଟଲ କରାଯାଇଛି।\nଅନୁମୋଦିତ ଅମୁମତିଗୁଡ଼ିକ ଭ୍ୟୁ କରିବା ପାଇଁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ଆପଣଙ୍କ ଆଡମିନ୍‌‌ ଅପଡେଟ୍‍ କରିଛନ୍ତି"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ଆପଣଙ୍କ ଆଡମିନ୍‌‌ ଡିଲିଟ୍‍ କରିଛନ୍ତି"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ଠିକ ଅଛି"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ବେଟେରୀ ସେଭର ଗାଢ଼ା ଥିମକୁ ଚାଲୁ କରେ ଏବଂ ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ ଇଫେକ୍ଟ, କିଛି ଫିଚର ଏବଂ କିଛି ନେଟୱାର୍କ ସଂଯୋଗକୁ ସୀମିତ କିମ୍ବା ବନ୍ଦ କରେ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 80ed484e2523..5d2cc7be3039 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ।\nਦਿੱਤੀਆਂ ਗਈਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ਠੀਕ ਹੈ"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ਬੈਟਰੀ ਸੇਵਰ ਗੂੜ੍ਹੇ ਥੀਮ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ, ਕੁਝ ਖਾਸ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਤੇ ਕੁਝ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨਾਂ ਨੂੰ ਸੀਮਤ ਜਾਂ ਬੰਦ ਕਰਦਾ ਹੈ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index efae947b3793..bb7edb8a79ad 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tryb jednej ręki"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatkowe przyciemnienie"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Urządzenia słuchowe"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatyczne kliknięcie"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Rozłączone"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Połączone"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktywne"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Zainstalowany przez administratora.\nOtwórz ustawienia, aby wyświetlić przyznane uprawnienia"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Zaktualizowany przez administratora"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne, pewne funkcje oraz wybrane połączenia sieciowe."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4036d636ae5c..0440e39a9dd5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Tela ainda mais escura"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clique automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index df3f9c6e2b63..745e17be6c28 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mais escuro"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clique automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desligado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Ligado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de soltar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir palavra-passe antes de soltar"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo seu administrador.\nAceda às definições para ver as autorizações concedidas"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu gestor"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado pelo seu gestor"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Poupança de bateria ativa o tema escuro e limita ou desativa a atividade em segundo plano, alguns efeitos visuais, determinadas funcionalidades e algumas ligações de rede."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4036d636ae5c..0440e39a9dd5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Tela ainda mais escura"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clique automático"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b12af3960d65..4ef0423b327b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modul cu o mână"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminozitate redusă suplimentar"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparate auditive"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automat"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Deconectat"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectat"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Activ"</string>
@@ -1967,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instalat de administrator.\nAccesează setările ca să vezi permisiunile acordate."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizat de administrator"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Șters de administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Economisirea bateriei activează tema întunecată și restricționează sau dezactivează activitatea în fundal, unele efecte vizuale, alte funcții și câteva conexiuni la rețea."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4911fc60d23e..a03963ef9924 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим управления одной рукой"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнительное уменьшение яркости"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слуховые аппараты"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автонажатие"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Отключено"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Подключено"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено администратором.\nЧтобы посмотреть предоставленные разрешения, перейдите в настройки."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Обновлено администратором"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Удалено администратором"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"В режиме энергосбережения включается тёмная тема, ограничиваются или отключаются фоновые процессы, а также некоторые визуальные эффекты, часть функций и сетевых подключений."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index b11e442bfeb8..571706e325c9 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"තනි අත් ප්‍රකාරය"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"තවත් අඳුරු"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ශ්‍රවණ උපාංග"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ස්වයං ක්ලික් කිරීම"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"විසන්ධි විය"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"සම්බන්ධිතයි"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"සක්‍රිය"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ඔබේ පරිපාලකයා විසින් ස්ථාපන කරනු ලබයි.\nදෙන ලද අවසර බැලීමට සැකසීම් වෙත යන්න"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"ඔබගේ පරිපාලක මඟින් යාවත්කාලීන කර ඇත"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ඔබගේ පරිපාලක මඟින් මකා දමා ඇත"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"හරි"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"බැටරි සුරැකුම අඳුරු තේමාව ක්‍රියාත්මක කර පසුබිම් ක්‍රියාකාරකම්, සමහර දෘශ්‍ය ප්‍රයෝග, යම් විශේෂාංග සහ සමහර ජාල සම්බන්ධතා සීමා හෝ ක්‍රියාවිරහිත කරයි."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 47bee0ad1bc9..bcbd66f55412 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednej ruky"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mimoriadne stmavenie"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Načúvacie zariadenia"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatické kliknutie"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Odpojené"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Pripojené"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktívne"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Nainštaloval správca.\nAk si chcete zobraziť udelené povolenia, prejdite do nastavení."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Šetrič batérie zapne tmavý motív a obmedzí alebo vypne aktivitu na pozadí, niektoré vizuálne efekty, určité funkcie a niektoré pripojenia k sieti."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 208c17463ce4..c0d18ed0a067 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni pripomočki"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Samodejni klik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Brez povezave"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odpenjanjem vprašaj za geslo"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Namestil skrbnik.\nV nastavitvah si oglejte odobrena dovoljenja."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Posodobil skrbnik"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisal skrbnik"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"V redu"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Funkcija varčevanja z energijo baterije vklopi temno temo ter omeji ali izklopi dejavnost v ozadju, nekatere vizualne učinke, določene funkcije in nekatere omrežne povezave."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 5f8490882bec..ddccedeaa36c 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modaliteti i përdorimit me një dorë"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Shumë më i zbehtë"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Pajisjet e dëgjimit"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Klikimi automatik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Shkëputur"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Lidhur"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktive"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Instaluar nga administratori.\nShko te cilësimet për të shikuar lejet e dhëna"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Përditësuar nga administratori"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Fshirë nga administratori"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Në rregull"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\"Kursyesi i baterisë\" aktivizon \"Temën e errët\" dhe kufizon ose çaktivizon aktivitetin në sfond, disa efekte vizuale, veçori të caktuara dhe disa lidhje të rrjetit."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 61102d3bb076..397a39458580 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1966,7 +1966,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index d5fc6948aa6f..71062addb40f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhandsläge"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradimmat"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörhjälpmedel"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatiskt klick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Frånkopplad"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Ansluten"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Be om upplåsningsmönster innan skärmen slutar fästas"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Be om lösenord innan skärmen slutar fästas"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Har installerats av administratören.\nÖppna inställningarna för att se behörigheter som beviljats"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Administratören uppdaterade paketet"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratören raderade paketet"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"I batterisparläget aktiveras mörkt tema medan bakgrundsaktivitet, vissa visuella effekter och funktioner samt vissa nätverksanslutningar begränsas eller inaktiveras."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 49e9f1cd64d5..e74ac1858d76 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Hali ya kutumia kwa mkono mmoja"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Kipunguza mwangaza zaidi"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Vifaa vya kusaidia kusikia"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Kubofya kiotomatiki"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Haijaunganishwa"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Imeunganishwa"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Inatumika"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Omba mchoro wa kufungua kabla hujabandua"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Omba nenosiri kabla hujabandua"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Kimewekwa na msimamizi wako.\nNenda kwenye mipangilio ili uone ruhusa zilizotolewa"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Imesasishwa na msimamizi wako"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Imefutwa na msimamizi wako"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Sawa"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Kiokoa Betri huwasha Mandhari meusi na kudhibiti au kuzima shughuli za chinichini, baadhi ya madoido yanayoonekana, vipengele fulani na baadhi ya miunganisho ya mtandao."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index dad40dc8f4c9..7737d8f6da45 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ஒற்றைக் கைப் பயன்முறை"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"மிகக் குறைவான வெளிச்சம்"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"செவித்துணைக் கருவிகள்"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ஆட்டோ கிளிக்"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"இணைப்புநீக்கப்பட்டது"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"இணைக்கப்பட்டுள்ளது"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"செயலில் உள்ளது"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"உங்கள் நிர்வாகி நிறுவியுள்ளார்.\nவழங்கப்பட்டுள்ள அனுமதிகளை பார்க்க அமைப்புகளுக்குச் செல்லவும்"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"உங்கள் நிர்வாகி நீக்கியுள்ளார்"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"சரி"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"பேட்டரி சேமிப்பான் அம்சம் டார்க் தீமை இயக்குவதோடு பின்னணிச் செயல்பாடு, சில விஷுவல் எஃபக்ட்கள், குறிப்பிட்ட அம்சங்கள், சில நெட்வொர்க் இணைப்புகள் ஆகியவற்றைக் கட்டுப்படுத்தும் அல்லது முடக்கும்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 322a703ccdbe..265fb8c9b382 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"వన్-హ్యాండెడ్ మోడ్"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ఎక్స్‌ట్రా డిమ్"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరాలు"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ఆటో-క్లిక్"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"డిస్‌కనెక్ట్ అయింది"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"కనెక్ట్ చేయబడింది"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"యాక్టివ్"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"అన్‌పిన్ చేయడానికి ముందు అన్‌లాక్ ఆకృతి కోసం అడుగు"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"అన్‌పిన్ చేయడానికి ముందు పాస్‌వర్డ్ కోసం అడుగు"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"మీ అడ్మిన్ ఇన్‌స్టాల్ చేశారు.\nసెట్టింగ్‌లకు వెళ్లి, మంజూరు చేసిన అనుమతులు చూడండి"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"మీ నిర్వాహకులు అప్‌డేట్ చేశారు"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"మీ నిర్వాహకులు తొలగించారు"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"సరే"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"బ్యాటరీ సేవర్ ముదురు రంగు రూపాన్ని ఆన్ చేసి, బ్యాక్‌గ్రౌండ్ యాక్టివిటీ, కొన్ని విజువల్ ఎఫెక్ట్‌లు, నిర్దిష్ట ఫీచర్‌లు, ఇంకా కొన్ని నెట్‌వర్క్ కనెక్షన్‌లను పరిమితం చేస్తుంది లేదా ఆఫ్ చేస్తుంది."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 107a59fb2829..a922943f54c7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1965,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ขอรูปแบบการปลดล็อกก่อนเลิกปักหมุด"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ขอรหัสผ่านก่อนเลิกปักหมุด"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"ติดตั้งโดยผู้ดูแลระบบของคุณ\nไปที่การตั้งค่าเพื่อดูสิทธิ์ที่ได้รับอนุญาต"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"อัปเดตโดยผู้ดูแลระบบ"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ลบโดยผู้ดูแลระบบ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ตกลง"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"โหมดประหยัดแบตเตอรี่จะเปิดธีมมืดและจำกัดหรือปิดกิจกรรมในเบื้องหลัง เอฟเฟกต์ภาพบางอย่าง ฟีเจอร์บางส่วน และการเชื่อมต่อบางเครือข่าย"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 97883270cda7..5e3e1e86c713 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-Hand mode"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Mga hearing device"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoclick"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nadiskonekta"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Nakakonekta"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktibo"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Humingi ng password bago mag-unpin"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Na-install ng iyong admin.\nPumunta sa mga setting para makita ang mga ibinigay na pahintulot"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Na-update ng iyong admin"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Na-delete ng iyong admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ino-on ng Pantipid ng Baterya ang Madilim na tema at nililimitahan o ino-off nito ang aktibidad sa background, ilang visual effect, ilang partikular na feature, at ilang koneksyon sa network."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 095a3da72ae1..72d62d5b2499 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tek El modu"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra loş"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"İşitme cihazları"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Otomatik tıklama"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Bağlı değil"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Bağlı"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Etkin"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Yöneticiniz tarafından yüklendi.\nVerilen izinleri görüntülemek için ayarlara gidin"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Yöneticiniz tarafından güncellendi"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Yöneticiniz tarafından silindi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Tamam"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Pil Tasarrufu, Koyu temayı açıp arka plan etkinliğini, bazı görsel efektleri, belirli özellikleri ve bazı ağ bağlantılarını sınırlandırır veya kapatır."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index bc05f49e0e6f..e4e1e99be263 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1805,8 +1805,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим керування однією рукою"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додаткове зменшення яскравості"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухові апарати"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Автоматичне натискання"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Від’єднано"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Під’єднано"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Активний"</string>
@@ -1968,7 +1967,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено адміністратором.\nПерейдіть у налаштування, щоб переглянути надані дозволи."</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Оновлено адміністратором"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Видалено адміністратором"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У режимі енергозбереження вмикається темна тема й обмежуються чи вимикаються дії у фоновому режимі, а також деякі візуальні ефекти, функції та з’єднання з мережами."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 7794c9af1f1f..a98179a3064b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ایک ہاتھ کی وضع"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"اضافی مدھم"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعتی آلات"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"خودکار کلک"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"غیر منسلک ہے"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"منسلک ہے"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"فعال"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"آپ کے منتظم نے انسٹال کیا ہے۔\nدی گئی اجازتیں دیکھنے کیلئے ترتیبات پر جائیں"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"آپ کے منتظم کے ذریعے اپ ڈیٹ کیا گیا"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"آپ کے منتظم کے ذریعے حذف کیا گیا"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ٹھیک ہے"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"بیٹری سیور گہری تھیم کو آن کرتی ہے اور پس منظر کی سرگرمی، کچھ بصری اثرات، مخصوص خصوصیات اور کچھ نیٹ ورک کنکشنز کو محدود یا آف کرتی ہے۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 95a44bbd5c3d..81ebe5fa7c2b 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ixcham rejim"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Juda xira"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eshitish qurilmalari"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Avtoklik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Uzildi"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Ulandi"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Faol"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Yechishdan oldin grafik kalit so‘ralsin"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bo‘shatishdan oldin parol so‘ralsin"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Administrator oʻrnatgan.\nBerilgan ruxsatlarni koʻrish uchun sozlamalarni oching"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Administrator tomonidan yangilangan"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Quvvat tejash funksiyasi Tungi mavzuni va cheklovlarni yoqadi hamda fondagi harakatlar, vizual effektlar, ayrim funksiyalar va tarmoq aloqalari kabi boshqa funksiyalarni faolsizlantiradi yoki cheklaydi."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index bb9b797e9ec2..4dda8cc0c8c1 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Chế độ một tay"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Siêu tối"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Thiết bị trợ thính"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Tự động nhấp"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Đã ngắt kết nối"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Đã kết nối"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Đang hoạt động"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Do quản trị viên của bạn cài đặt.\nChuyển đến phần cài đặt để xem các quyền được cấp"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Do quản trị viên của bạn cập nhật"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Do quản trị viên của bạn xóa"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Trình tiết kiệm pin sẽ bật Giao diện tối, đồng thời hạn chế hoặc tắt hoạt động chạy trong nền, một số hiệu ứng hình ảnh, các tính năng nhất định và một số đường kết nối mạng."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 108d62eb072c..851195acf204 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"单手模式"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"极暗"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听装置"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"自动点击"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"已断开连接"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"已连接"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"活跃"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定前要求绘制解锁图案"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消时要求输入密码"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"由您的管理员安装。\n前往设置可查看已授予的权限"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"已由您的管理员更新"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理员删除"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"确定"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"在省电模式下,系统会启用深色主题,并限制或关闭后台活动、某些视觉效果、特定功能和部分网络连接。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index fc9e6e8e506d..87b403d39207 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"自動點擊"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"已中斷連線"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"已連線"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"運作中"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"已由你的管理員安裝。\n請前往設定查看已授予的權限"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"好"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"「慳電模式」會開啟深色主題背景,並限制或關閉背景活動、部分視覺效果、特定功能和部分網絡連線。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d2ca941d7dd2..72d2e7ce3cc1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"自動點選"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"連線中斷"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"已連線"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"運作中"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須畫出解鎖圖案"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"這是管理員安裝的套件。\n你可以前往設定查看授予的權限"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"省電模式會開啟深色主題,並限制或關閉背景活動、某些視覺效果、特定功能和部分網路連線。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e11683200d30..13356cbcd356 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Imodi yesandla esisodwa"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ukufiphaza okwengeziwe"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Amadivayizi okuzwa"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Chofoza ngokuzenzekelayo"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Inqamukile"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Ixhunyiwe"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Kuyasebenza"</string>
@@ -1966,7 +1965,8 @@
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string>
<string name="package_installed_device_owner" msgid="8684974629306529138">"Kufakwe ngumphathi wakho.\nIya kumasethingi ukuze ubuke izimvume ezinikeziwe"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Kubuyekezwe umlawuli wakho"</string>
+ <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
+ <skip />
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Isilondolozi Sebhethri sivula ingqikithi emnyama futhi sibeke umkhawulo noma sivale umsebenzi ongemuva, imiphumela ethile yokubuka, izici ezithile, nokuxhumeka okuthile kwenethiwekhi."</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fbb8e25eeced..8c5b20da73ef 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2812,6 +2812,20 @@
<integer name="config_dreamsBatteryLevelDrainCutoff">5</integer>
<!-- Limit of how long the device can remain unlocked due to attention checking. -->
<integer name="config_attentionMaximumExtension">900000</integer> <!-- 15 minutes. -->
+
+ <!-- Enables or disables the 'prevent screen timeout' feature, where when a user manually
+ undims the screen, the feature acquires a wakelock to prevent screen timeout.
+ false = disabled, true = enabled. Disabled by default. -->
+ <bool name="config_defaultPreventScreenTimeoutEnabled">false</bool>
+ <!-- Default value (in milliseconds) to prevent the screen timeout after user undims it
+ manually between screen dims, a sign the user is interacting with the device. -->
+ <integer name="config_defaultPreventScreenTimeoutForMillis">300000</integer> <!-- 5 minutes. -->
+ <!-- Default max duration (in milliseconds) of the time between undims to still consider them
+ consecutive. -->
+ <integer name="config_defaultMaxDurationBetweenUndimsMillis">600000</integer> <!-- 10 min. -->
+ <!-- Default number of user undims required to trigger preventing screen sleep. -->
+ <integer name="config_defaultUndimsRequired">2</integer>
+
<!-- Whether there is to be a chosen Dock User who is the only user allowed to dream. -->
<bool name="config_dreamsOnlyEnabledForDockUser">false</bool>
<!-- Whether dreams are disabled when ambient mode is suppressed. -->
@@ -4459,6 +4473,10 @@
etc. dialogs. -->
<string translatable="false" name="config_appsNotReportingCrashes"></string>
+ <!-- Specifies the delay in milliseconds for JobScheduler to postpone the running
+ of regular jobs when coming out of doze -->
+ <integer name="config_jobSchedulerBackgroundJobsDelay">3000</integer>
+
<!-- Inactivity threshold (in milliseconds) used in JobScheduler. JobScheduler will consider
the device to be "idle" after being inactive for this long. -->
<integer name="config_jobSchedulerInactivityIdleThreshold">1860000</integer>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 6245a53b02f5..ef6b9188532e 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -80,11 +80,6 @@
<bool name="auto_data_switch_ping_test_before_switch">true</bool>
<java-symbol type="bool" name="auto_data_switch_ping_test_before_switch" />
- <!-- TODO: remove after V -->
- <!-- Boolean indicating whether allow to use a roaming nonDDS if user enabled its roaming. -->
- <bool name="auto_data_switch_allow_roaming">true</bool>
- <java-symbol type="bool" name="auto_data_switch_allow_roaming" />
-
<!-- Define the tolerated gap of score for auto data switch decision, larger than which the
device will switch to the SIM with higher score. The score is used in conjunction with the
score table defined in
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8d7a48e1b855..833761bad734 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3016,6 +3016,7 @@
<java-symbol type="integer" name="config_defaultNightMode" />
+ <java-symbol type="integer" name="config_jobSchedulerBackgroundJobsDelay" />
<java-symbol type="integer" name="config_jobSchedulerInactivityIdleThreshold" />
<java-symbol type="integer" name="config_jobSchedulerInactivityIdleThresholdOnStablePower" />
<java-symbol type="integer" name="config_jobSchedulerIdleWindowSlop" />
@@ -4444,6 +4445,11 @@
<!-- For Attention Service -->
<java-symbol type="integer" name="config_attentionMaximumExtension" />
+ <java-symbol type="bool" name="config_defaultPreventScreenTimeoutEnabled" />
+ <java-symbol type="integer" name="config_defaultPreventScreenTimeoutForMillis" />
+ <java-symbol type="integer" name="config_defaultMaxDurationBetweenUndimsMillis" />
+ <java-symbol type="integer" name="config_defaultUndimsRequired" />
+
<java-symbol type="string" name="config_incidentReportApproverPackage" />
<java-symbol type="array" name="config_restrictedImagesServices" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index f89e4416ce78..157c74abc5de 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -371,22 +371,22 @@ public class NotificationTest {
@Test
@EnableFlags(Flags.FLAG_UI_RICH_ONGOING)
- public void testHasPromotableStyle_bigPicture() {
+ public void testHasPromotableStyle_bigText() {
Notification n = new Notification.Builder(mContext, "test")
.setSmallIcon(android.R.drawable.sym_def_app_icon)
- .setStyle(new Notification.BigPictureStyle())
+ .setStyle(new Notification.BigTextStyle())
.build();
assertThat(n.hasPromotableStyle()).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_UI_RICH_ONGOING)
- public void testHasPromotableStyle_bigText() {
+ public void testHasPromotableStyle_no_bigPictureStyle() {
Notification n = new Notification.Builder(mContext, "test")
.setSmallIcon(android.R.drawable.sym_def_app_icon)
- .setStyle(new Notification.BigTextStyle())
+ .setStyle(new Notification.BigPictureStyle())
.build();
- assertThat(n.hasPromotableStyle()).isTrue();
+ assertThat(n.hasPromotableStyle()).isFalse();
}
@Test
diff --git a/core/tests/vibrator/src/android/os/ExternalVibrationTest.java b/core/tests/vibrator/src/android/os/ExternalVibrationTest.java
index 8741907cd5ea..9c9d50202486 100644
--- a/core/tests/vibrator/src/android/os/ExternalVibrationTest.java
+++ b/core/tests/vibrator/src/android/os/ExternalVibrationTest.java
@@ -49,4 +49,22 @@ public class ExternalVibrationTest {
assertThat(restored.getAudioAttributes()).isEqualTo(original.getAudioAttributes());
assertThat(restored.getToken()).isEqualTo(original.getToken());
}
+
+ @Test
+ public void testSerialization_systemUsage() {
+ ExternalVibration original =
+ new ExternalVibration(
+ 123,
+ "pkg",
+ new AudioAttributes.Builder()
+ .setSystemUsage(AudioAttributes.USAGE_SPEAKER_CLEANUP)
+ .build(),
+ IExternalVibrationController.Stub.asInterface(new Binder()));
+ Parcel p = Parcel.obtain();
+ original.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p);
+
+ assertThat(restored.getAudioAttributes()).isEqualTo(original.getAudioAttributes());
+ }
}
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 1e72d64397d7..ab2804626361 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -194,3 +194,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "enable_gsf"
+ namespace: "multitasking"
+ description: "Applies GSF font styles to multitasking."
+ bug: "400534660"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index 477d207a5c7e..16e098b39004 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -53,15 +53,12 @@
<com.android.wm.shell.windowdecor.HandleMenuImageButton
android:id="@+id/collapse_menu_button"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_marginEnd="16dp"
- android:layout_marginStart="14dp"
+ android:padding="16dp"
android:contentDescription="@string/collapse_menu_text"
- android:src="@drawable/ic_baseline_expand_more_24"
+ android:src="@drawable/ic_baseline_expand_more_16"
android:rotation="180"
android:tint="@androidprv:color/materialColorOnSurface"
- android:background="?android:selectableItemBackgroundBorderless"/>
+ style="@style/DesktopModeHandleMenuWindowingButton"/>
</LinearLayout>
<LinearLayout
@@ -145,6 +142,7 @@
android:contentDescription="@string/screenshot_text"
android:text="@string/screenshot_text"
android:src="@drawable/desktop_mode_ic_handle_menu_screenshot"
+ android:importantForAccessibility="no"
style="@style/DesktopModeHandleMenuActionButton"/>
<com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -152,6 +150,7 @@
android:contentDescription="@string/new_window_text"
android:text="@string/new_window_text"
android:src="@drawable/desktop_mode_ic_handle_menu_new_window"
+ android:importantForAccessibility="no"
style="@style/DesktopModeHandleMenuActionButton"/>
<com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -159,6 +158,7 @@
android:contentDescription="@string/manage_windows_text"
android:text="@string/manage_windows_text"
android:src="@drawable/desktop_mode_ic_handle_menu_manage_windows"
+ android:importantForAccessibility="no"
style="@style/DesktopModeHandleMenuActionButton"/>
<com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -166,6 +166,7 @@
android:contentDescription="@string/change_aspect_ratio_text"
android:text="@string/change_aspect_ratio_text"
android:src="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
+ android:importantForAccessibility="no"
style="@style/DesktopModeHandleMenuActionButton"/>
</LinearLayout>
@@ -185,6 +186,7 @@
android:text="@string/open_in_browser_text"
android:src="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
style="@style/DesktopModeHandleMenuActionButton"
+ android:importantForAccessibility="no"
android:layout_width="0dp"
android:layout_weight="1"/>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
index 0163c018479f..de38e6fc2330 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
@@ -34,5 +34,6 @@
<com.android.wm.shell.windowdecor.MarqueedTextView
android:id="@+id/label"
+ android:importantForAccessibility="no"
style="@style/DesktopModeHandleMenuActionButtonTextView"/>
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 4dffce59aec6..61dbb69761ad 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Links 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Links 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Volskerm regs"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Ruil boonste app met onderste een"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Ruil linkerapp met regterapp"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Volskerm bo"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Bo 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bo 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Herbegin"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Moenie weer wys nie"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dubbeltik om\nhierdie app te skuif"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimeer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Stel <xliff:g id="APP_NAME">%1$s</xliff:g> terug"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimeer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Maak <xliff:g id="APP_NAME">%1$s</xliff:g> toe"</string>
<string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
<string name="handle_text" msgid="4419667835599523257">"Apphandvatsel"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Verander grootte van linkerkantse venster"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Verander grootte van regterkantse venster"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimeer of stel venstergrootte terug"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimeer appvenstergrootte"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Stel venstergrootte terug"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimeer appvenster"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Maak appvenster toe"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Maak By Verstek Oop-instellings"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Kies hoe om webskakels vir hierdie app oop te maak"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In die app"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 0881e778fa52..52008a6ff952 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ግራ 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገፅ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ከላይ ያለውን መተግበሪያ ከታች ባለው ቀይር"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"በግራ ያለውን መተግበሪያን በቀኝ ባለው ቀይር"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገፅ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ከላይ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"እንደገና ያስጀምሩ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ዳግም አታሳይ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ይህን መተግበሪያ\nለማንቀሳቀስ ሁለቴ መታ ያድርጉ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን አሳድግ"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ወደነበረበት መልስ"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን አሳንስ"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ዝጋ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ተመለስ"</string>
<string name="handle_text" msgid="4419667835599523257">"የመተግበሪያ መያዣ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"መስኮትን ወደ ግራ መጠን ቀይር"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"መስኮትን ወደ ቀኝ መጠን ቀይር"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"የመስኮት መጠንን አሳድግ ወይም ወደነበረበት መልስ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"የመተግበሪያ መስኮት መጠንን አሳድግ"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"የመስኮት መጠንን ወደነበረበት መልስ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"የመተግበሪያ መስኮትን አሳንስ"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"የመተግበሪያ መስኮትን ዝጋ"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"በነባሪ ቅንብሮች ክፈት"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ለዚህ የድር መተግበሪያ አገናኙን እንዴት እንደሚከፍቱ ይምረጡ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"በመተግበሪያው ውስጥ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 9cc49aa144b5..65dd965afbf1 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ضبط حجم النافذة اليسرى ليكون ٣٠%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"عرض النافذة اليمنى بملء الشاشة"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"تبديل التطبيق العلوي بالسفلي"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"تبديل التطبيق الأيسر بالأيمن"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"عرض النافذة العلوية بملء الشاشة"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ضبط حجم النافذة العلوية ليكون ٧٠%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"إعادة التشغيل"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"عدم عرض مربّع حوار التأكيد مجددًا"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"انقر مرّتَين لنقل\nهذا التطبيق."</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"تكبير \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"استعادة \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"تصغير \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="close_button_text" msgid="4544839489310949894">"إغلاق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="back_button_text" msgid="1469718707134137085">"رجوع"</string>
<string name="handle_text" msgid="4419667835599523257">"مقبض التطبيق"</string>
<string name="app_icon_text" msgid="2823268023931811747">"رمز التطبيق"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"تغيير حجم النافذة بمحاذاتها إلى اليمين"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"تغيير حجم النافذة بمحاذاتها إلى اليسار"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"تكبير حجم النافذة أو استعادته"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"تكبير نافذة التطبيق"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"استعادة حجم النافذة"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"تصغير نافذة التطبيق"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"إغلاق نافذة التطبيق"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"إعدادات الفتح تلقائيًا"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"اختيار طريقة فتح روابط الويب لهذا التطبيق"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"في التطبيق"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index c59753c7803f..919447e125a1 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"বাওঁফালৰ স্ক্ৰীনখন ৫০% কৰক"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"বাওঁফালৰ স্ক্ৰীনখন ৩০% কৰক"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"সোঁফালৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"একেবাৰে তলৰ সৈতে একেবাৰে ওপৰৰ এপ্‌টো সলনাসলনি কৰক"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"সোঁফালৰ সৈতে বাওঁফালৰ এপ্‌টো সলনাসলনি কৰক"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"শীৰ্ষ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"শীর্ষ স্ক্ৰীনখন ৭০% কৰক"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ স্ক্ৰীনখন ৫০% কৰক"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ৰিষ্টাৰ্ট কৰক"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"পুনৰাই নেদেখুৱাব"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"এই এপ্‌টো\nস্থানান্তৰ কৰিবলৈ দুবাৰ টিপক"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> মেক্সিমাইজ কৰক"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক পুনঃস্থাপন কৰক"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> মিনিমাইজ কৰক"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> বন্ধ কৰক"</string>
<string name="back_button_text" msgid="1469718707134137085">"উভতি যাওক"</string>
<string name="handle_text" msgid="4419667835599523257">"এপৰ হেণ্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"সোঁফাললৈ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"বাওঁফাললৈ ৱিণ্ড’ৰ আকাৰ সলনি কৰক"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ৱিণ্ড’ৰ আকাৰ মেক্সিমাইজ বা পুনঃস্থাপন কৰক"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"এপ্‌ ৱিণ্ড’ৰ আকাৰ মেক্সিমাইজ কৰক"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ৱিণ্ড’ৰ আকাৰ পুনঃস্থাপন কৰক"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"এপ্‌ ৱিণ্ড’ মিনিমাইজ কৰক"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"এপ্‌ ৱিণ্ড’ বন্ধ কৰক"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফ’ল্ট ছেটিং খোলক"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"এই এপ্‌টোৰ বাবে কিদৰে ৱেব লিংক খুলিব পাৰি সেয়া বাছনি কৰক"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"এপ্‌টোত"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 63e610b53420..846240f80037 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sol 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Sol 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Sağ tam ekran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Yuxarıdakı tətbiqi aşağıdakı ilə dəyişdirin"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Soldakı tətbiqi sağdakı ilə dəyişdirin"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Yuxarı tam ekran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Yuxarı 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yuxarı 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Yenidən başladın"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Yenidən göstərməyin"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Tətbiqi köçürmək üçün\niki dəfə toxunun"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Böyüdün: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Bərpa edin: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Kiçildin: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Bağlayın: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Geriyə"</string>
<string name="handle_text" msgid="4419667835599523257">"Tətbiq ləqəbi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pəncərə ölçüsünü sola dəyişin"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pəncərə ölçüsünü sağa dəyişin"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Pəncərə ölçüsünü artırın və ya bərpa edin"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Tətbiq pəncərəsi ölçüsünü böyüdün"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Pəncərə ölçüsünü bərpa edin"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Tətbiq pəncərəsini kiçildin"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Tətbiq pəncərəsini bağlayın"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Defolt ayarlarla açın"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu tətbiq üçün veb-linklərin necə açılacağını seçin"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Tətbiqdə"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 4f3da2b2f5d8..d686da96d3d8 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левы экран – 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левы экран – 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Правы экран – поўнаэкранны рэжым"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Памяняць месцамі верхнюю і ніжнюю праграмы"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Памяняць месцамі левую і правую праграмы"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхні экран – поўнаэкранны рэжым"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхні экран – 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхні экран – 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Перазапусціць"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Больш не паказваць"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Каб перамясціць праграму,\nнацісніце двойчы"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Разгарнуць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Аднавіць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Згарнуць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Закрыць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Маркер праграмы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Змяніць памер акна і перамясціць да левага краю"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Змяніць памер акна і перамясціць да правага краю"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Разгарнуць акно ці аднавіць яго памер"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Разгарнуць акно праграмы"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Аднавіць памер акна"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Згарнуць акно праграмы"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Закрыць акно праграмы"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Налады параметра \"Адкрываць стандартна\""</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Выберыце, як гэта праграма будзе адкрываць вэб-спасылкі"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У праграме"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 3f867a22e13b..984c20ff5dba 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ляв екран: 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ляв екран: 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Десен екран: Показване на цял екран"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Размяна на горното и долното приложение"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Размяна на лявото и дясното приложение"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Горен екран: Показване на цял екран"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горен екран: 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горен екран: 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартиране"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Да не се показва отново"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Докоснете двукратно, за да\nпреместите това приложение"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Увеличаване на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Възстановяване на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Намаляване на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Затваряне на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Манипулатор за приложението"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Преоразмеряване на прозореца наляво"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Преоразмеряване на прозореца надясно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Увеличаване или възстановяване на размера на прозореца"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Увеличаване на размера на прозореца на приложението"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Възстановяване на размера на прозореца"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Намаляване на прозореца на приложението"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Затваряне на прозореца на приложението"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Отваряне на настройките по подразбиране"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Изберете как да се отварят уеб връзките за това приложение"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложението"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 3967d4bfa591..dd5653c48464 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"৫০% বাকি আছে"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"৩০% বাকি আছে"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ডান দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"নিচেরটির মাধ্যমে উপরের অ্যাপ অদল বদল করে নিন"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ডানদিকের মাধ্যমে বাঁদিকের অ্যাপ অদল বদল করে নিন"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"উপর দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"শীর্ষ ৭০%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ ৫০%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"রিস্টার্ট করুন"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"আর দেখতে চাই না"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"এই অ্যাপ সরাতে\nডবল ট্যাপ করুন"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> বড় করুন"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> আবার ফিরিয়ে আনুন"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ছোট করুন"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> বন্ধ করুন"</string>
<string name="back_button_text" msgid="1469718707134137085">"ফিরে যান"</string>
<string name="handle_text" msgid="4419667835599523257">"অ্যাপের হ্যান্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"অ্যাপ আইকন"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"বাঁদিকে উইন্ডো রিসাইজ করুন"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ডানদিকে উইন্ডো রিসাইজ করুন"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"উইন্ডো সাইজ বড় বা রিস্টোর করুন"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"অ্যাপ উইন্ডোর সাইজ বাড়ান"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"উইন্ডোর সাইজ ফিরিয়ে আনুন"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"অ্যাপ উইন্ডো ছোট করুন"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"অ্যাপ উইন্ডো বন্ধ করুন"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফল্ট হিসেবে থাকা সেটিংস খুলুন"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"এই অ্যাপের জন্য কীভাবে ওয়েব লিঙ্ক খুলবেন তা বেছে নিন"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"অ্যাপের মধ্যে"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 6b59d91e741f..01e0515dfa16 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevo 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Lijevo 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desno cijeli ekran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Zamjena gornje aplikacije donjom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Zamjena lijeve aplikacije desnom"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Gore cijeli ekran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gore 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gore 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Ponovo pokreni"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovo"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dodirnite dvaput da\npomjerite aplikaciju"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimiziranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Vraćanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimiziranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zatvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
<string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promjena veličine prozora i poravnanje lijevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promjena veličine prozora i poravnanje desno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimiziranje ili vraćanje veličine prozora"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimiziranje veličine prozora aplikacije"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Vraćanje veličine prozora"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimiziranje prozora aplikacije"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zatvaranje prozora aplikacije"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvaranje prema zadanim postavkama"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja web linkova za ovu aplikaciju"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 955e5cc6ecbc..77cf94b84450 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pantalla esquerra al 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Pantalla esquerra al 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla dreta completa"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Intercanvia l\'aplicació superior amb la inferior"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Intercanvia l\'aplicació esquerra amb la dreta"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Pantalla superior al 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Pantalla superior al 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reinicia"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No ho tornis a mostrar"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Fes doble toc per\nmoure aquesta aplicació"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximitza <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaura <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimitza <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Tanca <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Enrere"</string>
<string name="handle_text" msgid="4419667835599523257">"Identificador de l\'aplicació"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Canvia la mida de la finestra a l\'esquerra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Canvia la mida de la finestra a la dreta"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximitza o restaura la mida de la finestra"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximitza la mida de la finestra de l\'aplicació"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaura la mida de la finestra"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimitza la finestra de l\'aplicació"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Tanca la finestra de l\'aplicació"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Configuració d\'obertura predeterminada"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Tria com vols obrir els enllaços web per a aquesta aplicació"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"A l\'aplicació"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 673f7fc2f8c1..1a414ba89fdc 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % vlevo"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % vlevo"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pravá část na celou obrazovku"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Prohodit horní a dolní aplikaci"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Prohodit levou a pravou aplikaci"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Horní část na celou obrazovku"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % nahoře"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % nahoře"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartovat"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Tuto zprávu příště nezobrazovat"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dvojitým klepnutím\npřesunete aplikaci"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximalizovat aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Obnovit aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimalizovat aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zavřít aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Zpět"</string>
<string name="handle_text" msgid="4419667835599523257">"Popisovač aplikace"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Přichytit okno vlevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Přichytit okno vpravo"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximalizovat nebo obnovit velikost okna"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximalizovat velikost okna aplikace"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Obnovit velikost okna"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimalizovat okno aplikace"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zavřít okno aplikace"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Otevírat podle výchozího nastavení"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Určete, jak se v této aplikaci mají otevírat webové odkazy"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaci"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 635df334f9ff..07f1969ec9c6 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Venstre 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Venstre 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Vis højre del i fuld skærm"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Byt om på den øverste og nederste app"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Byt om på den venstre og højre app"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Vis øverste del i fuld skærm"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Øverste 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Øverste 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Genstart"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Vis ikke igen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Tryk to gange\nfor at flytte appen"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Gendan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Luk <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tilbage"</string>
<string name="handle_text" msgid="4419667835599523257">"Apphåndtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Juster størrelsen på vinduet til venstre"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Juster størrelsen på vinduet til højre"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimer eller gendan vinduesstørrelse"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimer størrelsen på appvinduet"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Gendan størrelsen på vinduet"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimer appvindue"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Luk appvindue"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Indstillinger for automatisk åbning"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Vælg, hvordan denne app skal åben weblinks"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 5be8b0b34993..7a8f2d984457 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % links"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % links"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Vollbild rechts"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Obere und untere App vertauschen"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Linke und rechte App vertauschen"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Vollbild oben"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % oben"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % oben"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Neu starten"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nicht mehr anzeigen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Zum Verschieben\ndoppeltippen"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> maximieren"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> wiederherstellen"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> minimieren"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> schließen"</string>
<string name="back_button_text" msgid="1469718707134137085">"Zurück"</string>
<string name="handle_text" msgid="4419667835599523257">"App-Ziehpunkt"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Fenstergröße nach links anpassen"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Fenstergröße nach rechts anpassen"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Fenstergröße maximieren oder wiederherstellen"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"App-Fenster maximieren"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Fenstergröße wiederherstellen"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"App-Fenster minimieren"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"App-Fenster schließen"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Einstellungen für die Option „Standardmäßig öffnen“"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Festlegen, wie Weblinks für diese App geöffnet werden"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In der App"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index bd3cf053836a..e2477d35881c 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Αριστερή 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Αριστερή 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Δεξιά πλήρης οθόνη"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Εναλλαγή της εφαρμογής στην κορυφή με αυτή στο κάτω μέρος"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Εναλλαγή της εφαρμογής στα αριστερά με αυτή στα δεξιά"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Πάνω πλήρης οθόνη"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Πάνω 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Πάνω 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Επανεκκίνηση"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Να μην εμφανιστεί ξανά"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Πατήστε δύο φορές για\nμετακίνηση αυτής της εφαρμογής"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Μεγιστοποίηση <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Επαναφορά <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Ελαχιστοποίηση <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Κλείσιμο <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Πίσω"</string>
<string name="handle_text" msgid="4419667835599523257">"Λαβή εφαρμογής"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Αλλαγή μεγέθους παραθύρου προς τα αριστερά"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Αλλαγή μεγέθους παραθύρου προς τα δεξιά"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Μεγιστοποίηση ή επαναφορά μεγέθους παραθύρου"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Μεγιστοποίηση μεγέθους παραθύρου εφαρμογής"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Επαναφορά μεγέθους παραθύρου"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Ελαχιστοποίηση παραθύρου εφαρμογής"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Κλείσιμο παραθύρου εφαρμογής"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Άνοιγμα ρυθμίσεων από προεπιλογή"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Επιλογή τρόπου ανοίγματος συνδέσμων ιστού για την εφαρμογή"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Στην εφαρμογή"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index b137d80dcd2b..bed6e5058a9f 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Swap top app with bottom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Swap left app with right"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Double-tap to\nmove this app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restore <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Close <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximise app window size"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restore window size"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimise app window"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Close app window"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index b137d80dcd2b..bed6e5058a9f 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Swap top app with bottom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Swap left app with right"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Double-tap to\nmove this app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restore <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Close <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximise app window size"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restore window size"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimise app window"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Close app window"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index b137d80dcd2b..bed6e5058a9f 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Swap top app with bottom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Swap left app with right"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Double-tap to\nmove this app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restore <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimise <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Close <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Back"</string>
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximise or restore window size"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximise app window size"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restore window size"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimise app window"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Close app window"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 1d5d3855bd23..2b7769d19168 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda: 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Izquierda: 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla derecha completa"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Intercambiar la app superior con la inferior"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Intercambiar la app de la izquierda con la de la derecha"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Superior: 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior: 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No volver a mostrar"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Presiona dos veces\npara mover esta app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restablecer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Cerrar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
<string name="handle_text" msgid="4419667835599523257">"Controlador de la app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícono de la app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ajustar el tamaño de la ventana hacia la izquierda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ajustar el tamaño de la ventana hacia la derecha"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar o restablecer el tamaño de la ventana"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar el tamaño de la ventana de la app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restablecer el tamaño de la ventana"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar ventana de la app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Cerrar ventana de la app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con la configuración predeterminada"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Elige cómo abrir vínculos web para esta app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la app"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index dfa7869434bc..afb1034551b3 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Izquierda 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla derecha completa"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Intercambiar aplicación superior con inferior"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Intercambiar aplicación izquierda con derecha"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Superior 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No volver a mostrar"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toca dos veces para\nmover esta aplicación"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Cerrar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
<string name="handle_text" msgid="4419667835599523257">"Controlador de la aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icono de la aplicación"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Cambiar tamaño de la ventana a la izquierda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Cambiar tamaño de la ventana a la derecha"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar o restaurar tamaño de la ventana"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar tamaño de la ventana de la aplicación"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurar tamaño de la ventana"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar ventana de la aplicación"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Cerrar ventana de la aplicación"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con los ajustes predeterminados"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Elige cómo quieres abrir los enlaces web de esta aplicación"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 294b7fee9954..61ca3e0db920 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasak: 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vasak: 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Parem täisekraan"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Ülemise ja alumise rakenduse vahetamine"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Vasaku ja parema rakenduse vahetamine"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ülemine täisekraan"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Ülemine: 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ülemine: 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Taaskäivita"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ära kuva uuesti"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Rakenduse teisaldamiseks\ntopeltpuudutage"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> maksimeerimine"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> taastamine"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> minimeerimine"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> sulgemine"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tagasi"</string>
<string name="handle_text" msgid="4419667835599523257">"Rakenduse element"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Akna suuruse muutmine, vasakule"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Akna suuruse muutmine, paremale"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Akna suuruse maksimeerimine või taastamine"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Rakenduse akna suuruse maksimeerimine"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Akna suuruse taastamined"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Rakenduse akna minimeerimine"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Rakenduse akna sulgemine"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Avamisviisi vaikeseaded"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Valige, kuidas avada selle rakenduse puhul veebilinke"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Rakenduses"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index a8f92128a603..af175bc9d08e 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ezarri ezkerraldea % 50en"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ezarri ezkerraldea % 30en"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ezarri eskuinaldea pantaila osoan"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Aldatu goiko aplikazioa behekoagatik"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Aldatu ezkerreko aplikazioa eskuinekoagatik"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ezarri goialdea pantaila osoan"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Ezarri goialdea % 70en"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ezarri goialdea % 50en"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Berrabiarazi"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ez erakutsi berriro"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Sakatu birritan\naplikazioa mugitzeko"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizatu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Leheneratu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizatu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Itxi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atzera"</string>
<string name="handle_text" msgid="4419667835599523257">"Aplikazioaren kontrol-puntua"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aplikazioaren ikonoa"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Aldatu leihoaren tamaina eta eraman ezkerrera"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Aldatu leihoaren tamaina eta eraman eskuinera"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizatu edo leheneratu leihoaren tamaina"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizatu aplikazioaren leihoaren tamaina"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Leheneratu leihoaren tamaina"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizatu aplikazioaren leihoa"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Itxi aplikazioaren leihoa"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Modu lehenetsian irekitzearen ezarpenak"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Aukeratu nola ireki sareko estekak aplikazio honetan"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Aplikazioan"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 59affd7887be..4df47c1dd2cf 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"٪۵۰ چپ"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"٪۳۰ چپ"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"تمام‌صفحه راست"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"جابه‌جا کردن برنامه بالا با پایین"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"جابه‌جا کردن برنامه چپ با راست"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"تمام‌صفحه بالا"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"٪۷۰ بالا"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"بازراه‌اندازی"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوباره نشان داده نشود"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"برای جابه‌جا کردن این برنامه\nدو تک‌ضرب بزنید"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"بزرگ کردن <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"بازیابی <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"کوچک کردن <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"بستن <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"برگشتن"</string>
<string name="handle_text" msgid="4419667835599523257">"دستگیره برنامه"</string>
<string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"تغییر اندازه پنجره به چپ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"تغییر اندازه پنجره به راست"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"بیشینه‌سازی یا بازیابی اندازه پنجره"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"بزرگ کردن اندازه پنجره برنامه"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"بازیابی اندازه پنجره"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"کوچک کردن پنجره برنامه"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"بستن پنجره برنامه"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"تنظیمات باز کردن به‌طور پیش‌فرض"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"انتخاب روش باز کردن پیوندهای وب مربوط به این برنامه"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"در برنامه"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index b1d8431b57d9..7da06bd50378 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasen 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vasen 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Oikea koko näytölle"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Vaihda ylä- ja alareunan sovellukset"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Vaihda vasen sovellus oikealla olevaan sovellukseen"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Yläosa koko näytölle"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Yläosa 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yläosa 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Käynnistä uudelleen"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Älä näytä uudelleen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Kaksoisnapauta, jos\nhaluat siirtää sovellusta"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Suurenna <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Palauta <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Pienennä <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Sulje <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Takaisin"</string>
<string name="handle_text" msgid="4419667835599523257">"Sovelluksen tunnus"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Muuta vasemmanpuoleisen ikkunan kokoa"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Muuta vasemmanpuoleisen ikkunan kokoa"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Suurenna ikkuna tai palauta ikkunan koko"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Suurenna sovellusikkunan koko"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Palauta ikkunan koko"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Pienennä sovellusikkuna"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Sulje sovellusikkuna"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Avaa oletusasetusten mukaan"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Valitse, miten verkkolinkit avataan tässä sovelluksessa"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sovelluksessa"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index c58f4b0610f1..d0fac37dc8ed 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % à la gauche"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % à la gauche"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Plein écran à la droite"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Inverser l\'appli du haut avec celle du bas"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Inverser l\'appli de gauche avec celle de droite"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Plein écran dans le haut"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % dans le haut"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % dans le haut"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toucher deux fois pour\ndéplacer cette appli"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Agrandir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Réduire <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Fermer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionner la fenêtre vers la gauche"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionner la fenêtre vers la droite"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Agrandir ou restaurer la taille de la fenêtre"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Agrandir la taille de la fenêtre de l\'appli"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurer la taille de la fenêtre"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Réduire la fenêtre de l\'appli"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Fermer la fenêtre de l\'appli"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choisissez comment ouvrir les liens Web pour cette appli"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'appli"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index e8db4c929561..91dc6de3a27f 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Écran de gauche à 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Écran de gauche à 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Écran de droite en plein écran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Inverser les applis du haut et du bas"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Inverser les applis de gauche et de droite"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Écran du haut en plein écran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Écran du haut à 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Écran du haut à 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Appuyez deux fois\npour déplacer cette appli"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Agrandir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Réduire <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Fermer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionner la fenêtre vers la gauche"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionner la fenêtre vers la droite"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Agrandir ou restaurer la taille de la fenêtre"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Agrandir la taille de la fenêtre de l\'application"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurer la taille de la fenêtre"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Réduire la fenêtre de l\'application"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Fermer la fenêtre de l\'application"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choisir comment ouvrir les liens Web pour cette appli"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'application"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index ba1c4a4b73c6..e315648c598d 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % á esquerda"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % á esquerda"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla completa á dereita"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Cambiar a aplicación de arriba pola de abaixo"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Cambiar a aplicación da esquerda pola da dereita"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla completa arriba"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % arriba"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % arriba"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Non mostrar outra vez"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toca dúas veces para\nmover esta aplicación"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Pechar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
<string name="handle_text" msgid="4419667835599523257">"Controlador da aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Axustar o tamaño da ventá á esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Axustar o tamaño da ventá á dereita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamaño da ventá"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar o tamaño da ventá da aplicación"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurar o tamaño da ventá"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar a ventá da aplicación"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Pechar a ventá da aplicación"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir coa configuración predeterminada"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escoller como abrir as ligazóns web para esta aplicación"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index d0be7d560961..cbcb2674c6b4 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बाईं स्क्रीन को 50% बनाएं"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"बाईं स्क्रीन को 30% बनाएं"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"दाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"सबसे ऊपर मौजूद ऐप्लिकेशन को सबसे नीचे मौजूद ऐप्लिकेशन से बदलें"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"बाईं ओर मौजूद ऐप्लिकेशन को दाईं ओर मौजूद ऐप्लिकेशन से बदलें"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ऊपर की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ऊपर की स्क्रीन को 70% बनाएं"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ऊपर की स्क्रीन को 50% बनाएं"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करें"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फिर से न दिखाएं"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ऐप्लिकेशन की जगह बदलने के लिए\nदो बार टैप करें"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> की विंडो को बड़ा करें"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> की विंडो को पहले जैसा करें"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> की विंडो को छोटा करें"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> को बंद करें"</string>
<string name="back_button_text" msgid="1469718707134137085">"वापस जाएं"</string>
<string name="handle_text" msgid="4419667835599523257">"ऐप्लिकेशन का हैंडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"विंडो का साइज़ बाईं ओर से बदलें"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"विंडो का साइज़ दाईं ओर से बढ़ाएं"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विंडो को बड़ा करें या उसका साइज़ पहले जैसा करें"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ऐप्लिकेशन की विंडो का साइज़ बड़ा करें"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"विंडो का साइज़ पहले जैसा करें"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ऐप्लिकेशन की विंडो को छोटा करें"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ऐप्लिकेशन की विंडो बंद करें"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफ़ॉल्ट सेटिंग के हिसाब से खोलें"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"इस ऐप्लिकेशन के लिए वेब लिंक खोलने का तरीका चुनें"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ऐप्लिकेशन में"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index d3e7599e1dc9..0eed0a422cf1 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevi zaslon na 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Lijevi zaslon na 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desni zaslon u cijeli zaslon"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Zamijeni gornju aplikaciju donjom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Zamijeni lijevu aplikaciju desnom"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Gornji zaslon u cijeli zaslon"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji zaslon na 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji zaslon na 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Pokreni ponovno"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovno"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dvaput dodirnite da biste\npremjestili ovu aplikaciju"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimiziraj aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Vrati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimiziraj aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zatvori aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Natrag"</string>
<string name="handle_text" msgid="4419667835599523257">"Pokazivač aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promijeni veličinu prozora ulijevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promijeni veličinu prozora udesno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimiziraj ili vrati veličinu prozora"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimiziraj prozor aplikacije"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Vrati veličinu prozora"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimiziraj prozor aplikacije"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zatvori prozor aplikacije"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvori prema zadanim postavkama"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja web-veza za ovu aplikaciju"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 2f7a21834eb8..48d5afd778c3 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Bal oldali 50%-ra"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Bal oldali 30%-ra"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Jobb oldali teljes képernyőre"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"A felső alkalmazás és az alsó alkalmazás felcserélése"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Bal és jobb alkalmazás felcserélése"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Felső teljes képernyőre"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Felső 70%-ra"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Felső 50%-ra"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Újraindítás"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne jelenjen meg többé"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Koppintson duplán\naz alkalmazás áthelyezéséhez"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> teljes méretűre állítása"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> visszaállítása"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> kis méretűre állítása"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> bezárása"</string>
<string name="back_button_text" msgid="1469718707134137085">"Vissza"</string>
<string name="handle_text" msgid="4419667835599523257">"App fogópontja"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ablak átméretezése balra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ablak átméretezése jobbra"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ablak teljes méretre állítása vagy visszaállítása"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Alkalmazásablak teljes méretre állítása"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Ablak méretének visszaállítása"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Alkalmazásablak kis méretre állítása"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Alkalmazás ablakának bezárása"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Alapértelmezett beállítások megnyitása"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Az app webes linkjeinek megnyitásához használt módszer"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Az alkalmazásban"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 2898dcc33b35..bf1e840179d5 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ձախ էկրանը՝ 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ձախ էկրանը՝ 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Աջ էկրանը՝ լիաէկրան"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Փոխեք վերևի հավելվածը վերևից"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Փոխեք ձախ հավելվածը աջից"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Վերևի էկրանը՝ լիաէկրան"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Վերևի էկրանը՝ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Վերևի էկրանը՝ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Վերագործարկել"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Այլևս ցույց չտալ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Կրկնակի հպեք՝\nհավելվածը տեղափոխելու համար"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Ծավալել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Վերականգնել «<xliff:g id="APP_NAME">%1$s</xliff:g>» միջոցառումը"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Ծալել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Փակել՝ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Հետ"</string>
<string name="handle_text" msgid="4419667835599523257">"Հավելվածի կեղծանուն"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ձգել պատուհանը դեպի ձախ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ձգել պատուհանը դեպի աջ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ծավալել կամ վերականգնել պատուհանի չափսը"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Առավելագույնի հասցրեք հավելվածի պատուհանի չափը"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Վերականգնել պատուհանի չափը"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Ծալել հավելվածի պատուհանը"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Փակեք հավելվածի պատուհանը"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Բացել կարգավորումներն ըստ կանխադրման"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Ընտրեք՝ ինչպես բացել այս հավելվածի վեբ հղումները"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Հավելվածում"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 617f9c99de01..d658f59ec9e3 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kiri 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Layar penuh di kanan"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Tukar aplikasi atas dengan aplikasi bawah"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Tukar aplikasi kiri dengan aplikasi kanan"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Layar penuh di atas"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Atas 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulai ulang"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tampilkan lagi"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Ketuk dua kali untuk\nmemindahkan aplikasi ini"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimalkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Pulihkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimalkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Tutup <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
<string name="handle_text" msgid="4419667835599523257">"Penanganan aplikasi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ubah ukuran jendela ke kiri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ubah ukuran jendela ke kanan"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimalkan atau pulihkan ukuran jendela"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimalkan ukuran jendela aplikasi"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Pulihkan ukuran jendela"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimalkan jendela aplikasi"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Tutup jendela aplikasi"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka dengan setelan default"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pilih cara membuka link web untuk aplikasi ini"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Di aplikasi"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 797a4cc8d035..f7b78d2222f5 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vinstri 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vinstri 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Hægri á öllum skjánum"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Víxla efsta og neðsta forriti"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Víxla hægra og vinstra forriti"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Efri á öllum skjánum"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Efri 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Efri 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Endurræsa"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ekki sýna þetta aftur"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Ýttu tvisvar til\nað færa þetta forrit"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Stækka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Endurheimta <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minnka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Loka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Til baka"</string>
<string name="handle_text" msgid="4419667835599523257">"Handfang forrits"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Breyta stærð glugga til vinstri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Breyta stærð glugga til hægri"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Hámarka eða endurheimta stærð glugga"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Hámarka stærð forritsglugga"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Endurheimta gluggastærð"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Lágmarka stærð forritsglugga"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Loka forritsglugga"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Stillingar sjálfvirkrar opnunar"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Veldu hvernig veftenglar opnast í forritinu"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Í forritinu"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 2fbe1a786687..369c019726c7 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"მარცხენა ეკრანი — 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"მარცხენა ეკრანი — 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"მარჯვენა ნაწილის სრულ ეკრანზე გაშლა"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ზედა და ქვედა აპების მდებარეობის გაცვლა"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"მარცხენა და მარჯვენა აპების მდებარეობის გაცვლა"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ზედა ნაწილის სრულ ეკრანზე გაშლა"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ზედა ეკრანი — 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ზედა ეკრანი — 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"გადატვირთვა"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"აღარ გამოჩნდეს"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ამ აპის გადასატანად\nორმაგად შეეხეთ მას"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის მაქსიმალურად გაშლა"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის აღდგენა"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის ჩაკეცვა"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დახურვა"</string>
<string name="back_button_text" msgid="1469718707134137085">"უკან"</string>
<string name="handle_text" msgid="4419667835599523257">"აპის იდენტიფიკატორი"</string>
<string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ფანჯრის ზომის შეცვლა მარცხნივ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ფანჯრის ზომის შეცვლა მარჯვნივ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ფანჯრის მაქსიმალურ ზომამდე გაზრდა ან აღდგენა"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"აპის ფანჯრის მაქსიმალურ ზომამდე გაზრდა"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ფანჯრის ზომის აღდგენა"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"აპის ფანჯრის ზომის შემცირება"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"აპის ფანჯრის დახურვა"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"პარამეტრების ნაგულისხმევად გახსნა"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ამ აპისთვის ვებ ბმულების გახსნის წესის არჩევა"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"აპში"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index c494b16687ef..1de32d4ae834 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% сол жақта"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% сол жақта"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Оң жағын толық экранға шығару"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Жоғарыдағы қолданбаны төмендегімен орнын ауыстыру"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Сол жақтағы қолданбаны оң жақтағымен орнын ауыстыру"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Жоғарғы жағын толық экранға шығару"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% жоғарғы жақта"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% жоғарғы жақта"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Өшіріп қосу"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Қайта көрсетілмесін"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Бұл қолданбаны басқа орынға\nжылжыту үшін екі рет түртіңіз."</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын ұлғайту"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын қалпына келтіру"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын кішірейту"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын жабу"</string>
<string name="back_button_text" msgid="1469718707134137085">"Артқа"</string>
<string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Терезе өлшемін сол жаққа өзгерту"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Терезе өлшемін оң жаққа өзгерту"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Терезе өлшемін ұлғайту не қалпына келтіру"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Қолданба терезесінің өлшемін ұлғайту"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Терезе өлшемін қалпына келтіру"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Қолданба терезесін кішірейту"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Қолданба терезесін жабу"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Әдепкісінше ашу параметрлері"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Осы қолданбадағы веб-сілтемелерді ашу жолын таңдаңыз"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Қолданбада"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 234c3552b7de..6c7faf1469eb 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ឆ្វេង 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ឆ្វេង 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"អេក្រង់ពេញខាងស្តាំ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ប្ដូរកម្មវិធីខាងលើគេទៅខាងក្រោម"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ប្ដូរកម្មវិធីខាងឆ្វេងទៅខាងស្ដាំ"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"អេក្រង់ពេញខាងលើ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ខាងលើ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ខាងលើ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ចាប់ផ្ដើម​ឡើង​វិញ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"កុំ​បង្ហាញ​ម្ដង​ទៀត"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ចុចពីរដងដើម្បី\nផ្លាស់ទីកម្មវិធីនេះ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"ពង្រីក <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"ស្ដារ <xliff:g id="APP_NAME">%1$s</xliff:g> ឡើងវិញ"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"បង្រួម <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"បិទ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"ថយក្រោយ"</string>
<string name="handle_text" msgid="4419667835599523257">"ឈ្មោះអ្នកប្រើប្រាស់កម្មវិធី"</string>
<string name="app_icon_text" msgid="2823268023931811747">"រូប​កម្មវិធី"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ប្ដូរទំហំវិនដូទៅឆ្វេង"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ប្ដូរទំហំវិនដូទៅស្ដាំ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ស្ដារ ឬបង្កើនទំហំវិនដូជាអតិបរមា"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ពង្រីកទំហំវិនដូកម្មវិធី"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ស្ដារទំហំវិនដូ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"បង្រួមវិនដូកម្មវិធី"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"បិទវិនដូកម្មវិធី"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ការកំណត់បើកតាមលំនាំដើម"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ជ្រើសរើសរបៀបបើកតំណបណ្ដាញសម្រាប់កម្មវិធីនេះ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"នៅក្នុងកម្មវិធី"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 61ee3c3915db..6a9e07f91d08 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% ಎಡಕ್ಕೆ"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% ಎಡಕ್ಕೆ"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ಬಲ ಫುಲ್ ಸ್ಕ್ರೀನ್"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ಮೇಲಿನ ಮತ್ತು ಕೆಳಗಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ಅದಲು-ಬದಲು ಮಾಡಿ"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ಎಡ ಮತ್ತು ಬಲದ ಆ್ಯಪ್‌ಗಳನ್ನು ಅದಲು-ಬದಲು ಮಾಡಿ"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ಮೇಲಿನ ಫುಲ್ ಸ್ಕ್ರೀನ್"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% ಮೇಲಕ್ಕೆ"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% ಮೇಲಕ್ಕೆ"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಸರಿಸಲು\nಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಿ"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಮಿನಿಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಮುಚ್ಚಿ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ಹಿಂದಕ್ಕೆ"</string>
<string name="handle_text" msgid="4419667835599523257">"ಆ್ಯಪ್ ಹ್ಯಾಂಡಲ್"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ವಿಂಡೋವನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ಮರುಗಾತ್ರಗೊಳಿಸಿ ವಿಂಡೋವನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ವಿಂಡೋ ಗಾತ್ರವನ್ನು ಗರಿಷ್ಠಗೊಳಿಸಿ ಅಥವಾ ಮರುಸ್ಥಾಪಿಸಿ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ಆ್ಯಪ್ ವಿಂಡೋದ ಗಾತ್ರವನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ವಿಂಡೋ ಗಾತ್ರವನ್ನು ಮರುಸ್ಥಾಪಿಸಿ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ಆ್ಯಪ್ ವಿಂಡೋವನ್ನು ಮಿನಿಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ಆ್ಯಪ್ ವಿಂಡೋವನ್ನು ಮುಚ್ಚಿರಿ"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ಡೀಫಾಲ್ಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ತೆರೆಯಿರಿ"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ಈ ಆ್ಯಪ್‌ಗೆ ವೆಬ್ ಲಿಂಕ್‌ಗಳನ್ನು ಹೇಗೆ ತೆರೆಯಬೇಕು ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ಆ್ಯಪ್‌ನಲ್ಲಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 2b36ba1eb3d7..e94d8893010f 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"왼쪽 화면 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"왼쪽 화면 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"오른쪽 화면 전체화면"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"상단 앱과 하단 앱 바꾸기"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"왼쪽 앱과 오른쪽 앱 바꾸기"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"위쪽 화면 전체화면"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"위쪽 화면 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"위쪽 화면 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"다시 시작"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"다시 표시 안함"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"두 번 탭하여\n이 앱 이동"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> 최대화"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> 복원"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> 최소화"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> 닫기"</string>
<string name="back_button_text" msgid="1469718707134137085">"뒤로"</string>
<string name="handle_text" msgid="4419667835599523257">"앱 핸들"</string>
<string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"창 크기 왼쪽으로 조절"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"창 크기 오른쪽으로 조절"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"창 최대화 또는 크기 복원"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"앱 창 크기 최대화"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"창 크기 복원"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"앱 창 최소화"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"앱 창 닫기"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"기본값으로 열기 설정"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"이 앱에서 웹 링크를 여는 방법을 선택하세요"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"앱에서"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index bb3c2fdae471..73e743686b77 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Сол жактагы экранды 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Сол жактагы экранды 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Оң жактагы экранды толук экран режимине өткөрүү"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Өйдө жактагы колдонмону ылдый жактагы менен алмаштыруу"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Сол жактагы колдонмону оң жактагы менен алмаштыруу"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Үстүнкү экранды толук экран режимине өткөрүү"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Үстүнкү экранды 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Үстүнкү экранды 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Өчүрүп күйгүзүү"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Экинчи көрүнбөсүн"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Бул колдонмону жылдыруу үчүн\nэки жолу таптаңыз"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> чоңойтуу"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> калыбына келтирүү"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> кичирейтүү"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> жабуу"</string>
<string name="back_button_text" msgid="1469718707134137085">"Артка"</string>
<string name="handle_text" msgid="4419667835599523257">"Колдонмонун маркери"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Терезенин өлчөмүн солго өзгөртүү"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Терезенин өлчөмүн оңго өзгөртүү"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Терезенин өлчөмүн чоңойтуу же калыбына келтирүү"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Колдонмонун терезесинин өлчөмүн чоңойтуу"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Колдонмонун терезесинин өлчөмүн калыбына келтирүү"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Колдонмонун терезесин кичирейтүү"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Колдонмонун терезесин жабуу"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Демейки шартта ачылуучу шилтемелердин параметрлери"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Колдонмодо шилтемелер кантип ачыларын тандаңыз"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Колдонмодо"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 8850923d8cca..fd47465de5da 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ຊ້າຍ 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ຊ້າຍ 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ເຕັມໜ້າຈໍຂວາ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ສະຫຼັບແອັບທາງເທິງກັບທາງລຸ່ມ"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ສະຫຼັບແອັບທາງຊ້າຍກັບທາງຂວາ"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ເຕັມໜ້າຈໍເທິງສຸດ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ເທິງສຸດ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ເທິງສຸດ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ຣີສະຕາດ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ບໍ່ຕ້ອງສະແດງອີກ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ແຕະສອງເທື່ອເພື່ອ\nຍ້າຍແອັບນີ້"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"ຂະຫຍາຍ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"ກູ້ຄືນ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"ຫຍໍ້ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"ປິດ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"ກັບຄືນ"</string>
<string name="handle_text" msgid="4419667835599523257">"ຊື່ຜູ້ໃຊ້ແອັບ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ປັບຂະໜາດໜ້າຈໍໄປທາງຊ້າຍ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ປັບຂະໜາດໜ້າຈໍໄປທາງຂວາ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ຂະຫຍາຍ ຫຼື ຄືນຄ່າຂະໜາດໜ້າຈໍ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ຂະຫຍາຍຂະໜາດໜ້າຈໍແອັບໃຫ້ໃຫຍ່ສຸດ"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ກູ້ຄືນຂະໜາດໜ້າຈໍ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ຫຍໍ້ໜ້າຈໍແອັບ"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ປິດໜ້າຈໍແອັບ"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ເປີດຕາມການຕັ້ງຄ່າເລີ່ມຕົ້ນ"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ເລືອກວິທີເປີດລິ້ງເວັບສຳລັບແອັບນີ້"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ໃນແອັບ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 8ed826aa11fc..902ef048b11e 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kairysis ekranas 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kairysis ekranas 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Dešinysis ekranas viso ekrano režimu"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Sukeisti viršutiniąją programą su apatiniąja"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Sukeisti kairiąją programą su dešiniąja"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Viršutinis ekranas viso ekrano režimu"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Viršutinis ekranas 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Viršutinis ekranas 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Paleisti iš naujo"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Daugiau neberodyti"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dukart palieskite, kad\nperkeltumėte šią programą"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Padidinti „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Atkurti „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Sumažinti „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Uždaryti „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atgal"</string>
<string name="handle_text" msgid="4419667835599523257">"Programos kreipinys"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pakeisti lango dydį kairėje"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pakeisti lango dydį dešinėje"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Padidinti arba atkurti lango dydį"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Padidinti programos lango dydį"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Atkurti lango dydį"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Sumažinti programos langą"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Uždaryti programos langą"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Atidaryti pagal numatytuosius nustatymus"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pasirinkite, kaip atidaryti šios programos žiniatinklio nuorodas"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Programoje"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 1227055b3222..b4095dfd6f1e 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pa kreisi 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Pa kreisi 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Labā daļa pa visu ekrānu"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Apmainīt vietām lietotni augšpusē ar lietotni apakšpusē"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Apmainīt vietām lietotni kreisajā pusē ar lietotni labajā pusē"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Augšdaļa pa visu ekrānu"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Augšdaļa 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Augšdaļa 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartēt"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Vairs nerādīt"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Veiciet dubultskārienu,\nlai pārvietotu šo lietotni"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimizēt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Atjaunot lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizēt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Aizvērt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Atpakaļ"</string>
<string name="handle_text" msgid="4419667835599523257">"Lietotnes turis"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Mainīt loga lielumu uz kreiso pusi"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Mainīt loga lielumu uz labo pusi"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimizēt vai atjaunot loga lielumu"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimizēt lietotnes loga lielumu"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Atjaunot loga lielumu"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizēt lietotnes logu"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Aizvērt lietotnes logu"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Atvērt pēc noklusējuma iestatījumiem"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Izvēlieties, kā atvērt šajā lietotnē norādītās saites"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Lietotnē"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index eb513748cdba..be97489d6159 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левиот 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левиот 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Десниот на цел екран"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Заменете ги местата на горната и долната апликација"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Заменете ги местата на левата и десната апликација"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Горниот на цел екран"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горниот 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горниот 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартирај"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Не прикажувај повторно"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Допрете двапати за да ја\nпоместите апликацијава"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Максимизирај <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Врати <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Минимизирај <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Затвори <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Прекар на апликацијата"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Променете ја големината на прозорецот налево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Променете ја големината на прозорецот надесно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Максимизирајте или вратете ја големината на прозорецот"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Максимизирај ја големината на прозорецот на апликацијата"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Врати ја големината на прозорецот"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Минимизирај го прозорецот на апликацијата"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Затвори го прозорецот на апликацијата"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Отвори според стандардните поставки"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Изберете како да се отвораат линковите за апликацијава"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Во апликацијата"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index fca2f7ce9177..d8efd8b2a103 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Зүүн 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Зүүн 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Баруун талын бүтэн дэлгэц"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Дээд талын аппыг доод талынхаар солих"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Зүүн талын аппыг баруун талынхаар солих"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Дээд талын бүтэн дэлгэц"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Дээд 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Дээд 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Дахин эхлүүлэх"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Дахиж бүү харуул"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Энэ аппыг зөөхийн тулд\nхоёр товшино уу"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г томруулах"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г сэргээх"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г жижгэрүүлэх"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г хаах"</string>
<string name="back_button_text" msgid="1469718707134137085">"Буцах"</string>
<string name="handle_text" msgid="4419667835599523257">"Аппын бариул"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Цонхны хэмжээг зүүн тал руу өөрчлөх"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Цонхны хэмжээг баруун тал руу өөрчлөх"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Цонхны хэмжээг томруулах эсвэл сэргээх"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Аппын цонхны хэмжээг томруулах"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Цонхны хэмжээг сэргээх"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Аппын цонхыг жижгэрүүлэх"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Аппын цонхыг хаах"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Өгөгдмөл тохиргоогоор нээх"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Энэ аппад веб холбоосыг хэрхэн нээхийг сонгоно уу"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Аппад"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 888118732b1a..d09a78426669 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"डावी 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"डावी 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"उजवी फुल स्क्रीन"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"सर्वात वरचे अ‍ॅप हे तळाशी असलेल्या अ‍ॅपने स्वॅप करा"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"डावीकडील अ‍ॅप हे उजवीकडील अ‍ॅपने स्वॅप करा"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"शीर्ष फुल स्क्रीन"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"शीर्ष 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"शीर्ष 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करा"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"पुन्हा दाखवू नका"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"हे ॲप हलवण्यासाठी\nदोनदा टॅप करा"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> मोठे करा"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> रिस्टोअर करा"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> लहान करा"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> बंद करा"</string>
<string name="back_button_text" msgid="1469718707134137085">"मागे जा"</string>
<string name="handle_text" msgid="4419667835599523257">"अ‍ॅपचे हँडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"अ‍ॅप आयकन"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"अ‍ॅप विंडोचा डावीकडे आकार बदला"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"अ‍ॅप विंडोचा उजवीकडे आकार बदला"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विंडोचा आकार मोठा करा किंवा रिस्टोअर करा"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"अ‍ॅप विंडोचा आकार मोठा करा"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"विंडोचा आकार रिस्टोअर करा"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"अ‍ॅप विंडो लहान करा"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"अ‍ॅप विंडो बंद करा"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"बाय डीफॉल्ट सेटिंग्ज उघडा"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"या अ‍ॅपसाठीच्या वेब लिंक कशा उघडाव्यात हे निवडा"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ॲपमध्ये"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 3451701a0456..2342564930b4 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ဘယ်ဘက် မျက်နှာပြင် ၃၀%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ညာဘက် မျက်နှာပြင်အပြည့်"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"အပေါ်အက်ပ်ကို အောက်သို့ ပြောင်းရန်"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ဘယ်ဘက်အက်ပ်ကို ညာဘက်သို့ ပြောင်းရန်"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"အပေါ်ဘက် မျက်နှာပြင်အပြည့်"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"အပေါ်ဘက် မျက်နှာပြင် ၇၀%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ပြန်စရန်"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"နောက်ထပ်မပြပါနှင့်"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ဤအက်ပ်ကို ရွှေ့ရန်\nနှစ်ချက်တို့ပါ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> ချဲ့ရန်"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ပြန်ယူရန်"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ချုံ့ရန်"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> ပိတ်ရန်"</string>
<string name="back_button_text" msgid="1469718707134137085">"နောက်သို့"</string>
<string name="handle_text" msgid="4419667835599523257">"အက်ပ်သုံးသူအမည်"</string>
<string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ဝင်းဒိုးကို ဘယ်ဘက်သို့ အရွယ်ပြင်ရန်"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ဝင်းဒိုးကို ညာဘက်သို့ အရွယ်ပြင်ရန်"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ဝင်းဒိုးအရွယ်အစားကို ချဲ့ရန် (သို့) ပြန်ပြောင်းရန်"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"အက်ပ်ဝင်းဒိုး အရွယ်အစားကို ချဲ့ရန်"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ဝင်းဒိုးအရွယ်အစား ပြန်ပြောင်းရန်"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"အက်ပ်ဝင်းဒိုးကို ချုံ့ရန်"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"အက်ပ်ဝင်းဒိုးကို ပိတ်ရန်"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"မူရင်းဆက်တင်ဖြင့် ဖွင့်ရန်"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ဤအက်ပ်အတွက် ဝဘ်လင့်ခ်များ မည်သို့ဖွင့်မည်ကို ရွေးပါ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"အက်ပ်တွင်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 3a4100c5f154..fb61a105eaaa 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Sett størrelsen på den venstre delen av skjermen til 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Utvid den høyre delen av skjermen til hele skjermen"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Bytt om på den øvre og nedre appen"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Bytt om på venstre og høyre app"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Utvid den øverste delen av skjermen til hele skjermen"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Sett størrelsen på den øverste delen av skjermen til 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Start på nytt"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ikke vis dette igjen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dobbelttrykk for\nå flytte denne appen"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Gjenopprett <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Lukk <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tilbake"</string>
<string name="handle_text" msgid="4419667835599523257">"Apphåndtak"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Endre størrelsen på vinduet til venstre"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Endre størrelsen på vinduet til høyre"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimer eller gjenopprett størrelsen på vinduet"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimer størrelsen på appvinduet"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Gjenopprett vindusstørrelsen"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimer appvinduet"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Lukk appvinduet"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Innstillinger for åpning som standard"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Velg hvordan nettlinker skal åpnes for denne appen"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index cc31e384260c..fdfa227b8080 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बायाँ भाग ५०%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"बायाँ भाग ३०%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"दायाँ भाग फुल स्क्रिन"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"सिरान र पुछारको एप अदलबदल गर्नुहोस्"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"दायाँ र बायाँतिरको एप अदलबदल गर्नुहोस्"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"माथिल्लो भाग फुल स्क्रिन"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"माथिल्लो भाग ७०%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"माथिल्लो भाग ५०%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"रिस्टार्ट गर्नुहोस्"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फेरि नदेखाउनुहोस्"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"यो एप सार्न डबल\nट्याप गर्नुहोस्"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> म्याक्सिमाइज गर्नुहोस्"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> रिस्टोर गर्नुहोस्"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> मिनिमाइज गर्नुहोस्"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> बन्द गर्नुहोस्"</string>
<string name="back_button_text" msgid="1469718707134137085">"पछाडि"</string>
<string name="handle_text" msgid="4419667835599523257">"एपको ह्यान्डल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"विन्डोको आकार बदलेर बायाँतिर लैजानुहोस्"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"विन्डोको आकार बदलेर दायाँतिर लैजानुहोस्"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"विन्डोको आकार म्याक्सिमाइज गर्नुहोस् वा रिस्टोर गर्नुहोस्"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"एपको विन्डोको आकार म्याक्सिमाइज गर्नुहोस्"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"विन्डोको आकार रिस्टोर गर्नुहोस्"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"एपको विन्डो मिनिमाइज गर्नुहोस्"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"एपको विन्डो बन्द गर्नुहोस्"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफल्ट सेटिङअनुसार खोल्नुहोस्"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"यो एपका वेब लिंकहरू खोल्ने तरिका छनौट गर्नुहोस्"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"एपमा"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 4234ddf0e456..578877c65dd1 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Linkerscherm 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Linkerscherm 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Rechterscherm op volledig scherm"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Apps bovenaan en onderaan omwisselen"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Apps links en rechts omwisselen"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Bovenste scherm op volledig scherm"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Bovenste scherm 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Opnieuw opstarten"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Niet opnieuw tonen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dubbeltik om\ndeze app te verplaatsen"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> maximaliseren"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> herstellen"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> minimaliseren"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> sluiten"</string>
<string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
<string name="handle_text" msgid="4419667835599523257">"App-handgreep"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Formaat van venster naar links aanpassen"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Formaat van venster naar rechts aanpassen"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Formaat van venster maximaliseren of herstellen"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Formaat van app-venster maximaliseren"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Vensterformaat herstellen"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"App-venster minimaliseren"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"App-venster sluiten"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Instellingen voor Standaard openen"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Kies hoe je weblinks voor deze app wilt openen"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In de app"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 59deb01e689f..50861bac617b 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% lewej części ekranu"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% lewej części ekranu"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Prawa część ekranu na pełnym ekranie"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Zamień aplikację na górze z tą na dole"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Zamień aplikację po lewej z tą po prawej"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Górna część ekranu na pełnym ekranie"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% górnej części ekranu"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% górnej części ekranu"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Uruchom ponownie"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nie pokazuj ponownie"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Aby przenieść aplikację,\nkliknij dwukrotnie"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksymalizuj okno aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Przywróć rozmiar okna aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimalizuj okno aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zamknij <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Wstecz"</string>
<string name="handle_text" msgid="4419667835599523257">"Uchwyt aplikacji"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacji"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Zmień rozmiar okna do lewej"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Zmień rozmiar okna do prawej"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Zmaksymalizuj lub przywróć rozmiar okna"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksymalizuj rozmiar okna aplikacji"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Przywróć rozmiar okna"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimalizuj okno aplikacji"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zamknij okno aplikacji"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Ustawienia domyślnego otwierania"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Wybierz, gdzie chcesz otwierać linki z tej aplikacji"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"W aplikacji"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 593f830e0d6e..a8f7403a94db 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Esquerda a 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Lado direito em tela cheia"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Trocar o app de cima pelo de baixo"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Trocar o app da esquerda pelo da direita"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Parte superior em tela cheia"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Parte superior a 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar novamente"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toque duas vezes para\nmover o app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Fechar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamanho da janela"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar o tamanho da janela do app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurar o tamanho da janela"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar janela do app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Fechar janela do app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para este app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index fcf59163be83..04d404287327 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% no ecrã esquerdo"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% no ecrã esquerdo"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ecrã direito inteiro"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Trocar app superior pela inferior"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Trocar app da esquerda pela da direita"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ecrã superior inteiro"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% no ecrã superior"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% no ecrã superior"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar de novo"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toque duas vezes\npara mover esta app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Fechar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Anterior"</string>
<string name="handle_text" msgid="4419667835599523257">"Indicador da app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar tamanho da janela"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar tamanho da janela da app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurar tamanho da janela"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar janela da app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Fechar janela da app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Definições de Abrir por predefinição"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para esta app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na app"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 593f830e0d6e..a8f7403a94db 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Esquerda a 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Lado direito em tela cheia"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Trocar o app de cima pelo de baixo"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Trocar o app da esquerda pelo da direita"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Parte superior em tela cheia"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Parte superior a 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar novamente"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toque duas vezes para\nmover o app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restaurar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Fechar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionar janela para a esquerda"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionar janela para a direita"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizar ou restaurar o tamanho da janela"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizar o tamanho da janela do app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restaurar o tamanho da janela"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizar janela do app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Fechar janela do app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para este app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 81db82a8c526..d781d0893fa6 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Partea stângă: 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Partea stângă: 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Partea dreaptă pe ecran complet"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Schimbă aplicația de sus cu cea de jos"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Schimbă aplicația din stânga cu cea din dreapta"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Partea de sus pe ecran complet"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Partea de sus: 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Partea de sus: 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Repornește"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nu mai afișa"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Atinge de două ori\nca să muți aplicația"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximizează <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restabilește <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizează <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Închide <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Înapoi"</string>
<string name="handle_text" msgid="4419667835599523257">"Handle de aplicație"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Redimensionează fereastra la stânga"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Redimensionează fereastra la dreapta"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximizează sau restabilește dimensiunea ferestrei"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximizează dimensiunea ferestrei aplicației"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restabilește dimensiunea ferestrei"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizează fereastra aplicației"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Închide fereastra aplicației"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Setări de deschidere în mod prestabilit"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Alege modul de deschidere a linkurilor web pentru aplicație"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"În aplicație"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index aa6f484debee..1837c31cbeef 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левый на 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левый на 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Правый во весь экран"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Поменять местами приложения сверху и снизу"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Поменять местами приложения слева и справа"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхний во весь экран"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхний на 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхний на 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Перезапустить"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Больше не показывать"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Дважды нажмите, чтобы\nпереместить приложение."</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Развернуть окно приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Восстановить окно приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Свернуть окно приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Закрыть окно приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Обозначение приложения"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Растянуть окно влево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Растянуть окно вправо"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Развернуть окно или восстановить его размер"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Развернуть окно приложения"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Восстановить размер окна"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Свернуть окно приложения"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Закрыть окно приложения"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Настройки, регулирующие, как по умолчанию открываются ссылки"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Выберите, где будут открываться ссылки из этого приложения"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложении"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index efa978aa4505..d2fc08229793 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"වම් 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"වම් 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"දකුණු පූර්ණ තිරය"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ඉහළ යෙදුම පහළ සමග මාරු කරන්න"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"වම් යෙදුම දකුණ සමග මාරු කරන්න"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ඉහළම පූර්ණ තිරය"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ඉහළම 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ඉහළම 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"යළි අරඹන්න"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"නැවත නොපෙන්වන්න"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"මෙම යෙදුම ගෙන යාමට\nදෙවරක් තට්ටු කරන්න"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> විහිදන්න"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ප්‍රතිසාධනය කරන්න"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> කුඩා කරන්න"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> වසන්න"</string>
<string name="back_button_text" msgid="1469718707134137085">"ආපසු"</string>
<string name="handle_text" msgid="4419667835599523257">"යෙදුම් හසුරුව"</string>
<string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"කවුළුව වමට ප්‍රතිප්‍රමාණ කරන්න"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"කවුළුව දකුණට ප්‍රතිප්‍රමාණ කරන්න"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"කවුළු ප්‍රමාණය උපරිම කරන්න හෝ ප්‍රතිසාධනය කරන්න"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"යෙදුම් කවුළු ප්‍රමාණය උපරිම කරන්න"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"කවුළු ප්‍රමාණය ප්‍රතිසාධනය කරන්න"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"යෙදුම් කවුළුව අවම කරන්න"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"යෙදුම් කවුළුව වසන්න"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"පෙරනිමි සැකසීම් මඟින් විවෘත කරන්න"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"මෙම යෙදුම සඳහා වෙබ් සබැඳි විවෘත කරන ආකාරය තෝරා ගන්න"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"යෙදුම තුළ"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index fac26b49819a..a9c81a2e59ad 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ľavá – 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ľavá – 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pravá– na celú obrazovku"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Vymeniť hornú aplikáciu za dolnú"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Vymeniť ľavú aplikáciu za pravú"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Horná – na celú obrazovku"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Horná – 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Horná – 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Reštartovať"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Už nezobrazovať"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Túto aplikáciu\npresuniete dvojitým klepnutím"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maximalizovať <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Obnoviť <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimalizovať <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zavrieť <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Späť"</string>
<string name="handle_text" msgid="4419667835599523257">"Rukoväť aplikácie"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Zmeniť veľkosť okna vľavo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Zmeniť veľkosť okna vpravo"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximalizovať alebo obnoviť veľkosť okna"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximalizovať veľkosť okna aplikácie"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Obnoviť veľkosť okna"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimalizovať okno aplikácie"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zavrieť okno aplikácie"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvárať podľa predvolených nastavení"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Vyberte, ako sa majú v tejto aplikácii otvárať webové odkazy"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikácii"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index f8dacc4fde23..8dcca185e374 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desni v celozaslonski način"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Zamenjava zgornje aplikacije s spodnjo"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Zamenjava leve aplikacije z desno"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Zgornji v celozaslonski način"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Zgornji 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Zgornji 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Znova zaženi"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikaži več"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dvakrat se dotaknite\nza premik te aplikacije"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Povečanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Obnovitev aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Pomanjšava aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zapiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazaj"</string>
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Sprememba velikosti okna na levi"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Sprememba velikosti okna na desni"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Povečava ali obnovitev velikosti okna"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Povečanje velikosti okna aplikacije"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Obnovitev velikosti okna"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Pomanjšava okna aplikacije"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zapiranje okna aplikacije"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Nastavitve privzetega odpiranja"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Izberite način odpiranja spletnih povezav za to aplikacijo"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 3e88ed15aff1..6f8bdef18dfe 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Majtas 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Majtas 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ekrani i plotë djathtas"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Ndërro aplikacionin lart me atë poshtë"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Ndërro aplikacionin majtas me atë djathtas"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ekrani i plotë lart"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Lart 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Lart 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Rinis"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Mos e shfaq përsëri"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Trokit dy herë për të\nlëvizur këtë aplikacion"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimizo \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Restauro \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimizo \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Mbyll \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="back_button_text" msgid="1469718707134137085">"Pas"</string>
<string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ndrysho përmasat e dritares në të majtë"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ndrysho përmasat e dritares në të djathtë"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimizo ose restauro madhësinë e dritares"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimizo madhësinë e dritares së aplikacionit"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Restauro madhësinë e dritares"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimizo dritaren e aplikacionit"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Mbyll dritaren e aplikacionit"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Hap sipas cilësimeve të parazgjedhura"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Zgjidh si do t\'i hapësh lidhjet e uebit për këtë aplikacion"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Në aplikacion"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 0105e158ac08..d8893dfab5f1 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vänster 50 %"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vänster 30 %"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Helskärm på höger skärm"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Byt plats på den översta och understa appen"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Byt plats på den vänstra och högra appen"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Helskärm på övre skärm"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Övre 70 %"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Övre 50 %"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Starta om"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Visa inte igen"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Tryck snabbt två gånger\nför att flytta denna app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Utöka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Återställ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimera <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Stäng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Tillbaka"</string>
<string name="handle_text" msgid="4419667835599523257">"Apphandtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ändra storlek på fönstret åt vänster"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ändra storlek på fönstret åt höger"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximera eller återställ fönsterstorleken"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maximera appfönstrets storlek"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Återställ fönsterstorlek"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimera appfönstret"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Stäng appfönstret"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Inställningar för Öppna som standard"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Välj hur webblänkar ska öppnas för den här appen"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index b4415cb58b87..3ee43f3a69a8 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kushoto 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kushoto 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Skrini nzima ya kulia"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Badilisha nafasi ya programu ya juu na ya chini"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Badilisha nafasi ya programu ya kulia na ya kushoto"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Skrini nzima ya juu"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Juu 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Juu 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Zima kisha uwashe"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Usionyeshe tena"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Gusa mara mbili ili\nusogeze programu hii"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Panua <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Rejesha <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Punguza <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Funga <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Rudi nyuma"</string>
<string name="handle_text" msgid="4419667835599523257">"Utambulisho wa programu"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Badilisha ukubwa wa dirisha kushoto"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Badilisha ukubwa wa dirisha kulia"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Panua au urejeshe ukubwa wa dirisha"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Panua ukubwa wa dirisha la programu"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Rejesha ukubwa wa dirisha"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Punguza dirisha la programu"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Funga dirisha la programu"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Fungua kwa mipangilio chaguomsingi"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Chagua jinsi ya kufungua viungo vya wavuti vya programu hii"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Kwenye programu"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index ccc9f9423e8a..a0e7c6acfb05 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"இடது புறம் 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"இடது புறம் 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"வலது புறம் முழுத் திரை"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"மேலுள்ள ஆப்ஸைக் கீழுள்ள ஆப்ஸ் கொண்டு மாற்றும்"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"இடதுபுற ஆப்ஸை வலதுபுற ஆப்ஸ் கொண்டு மாற்றும்"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"மேற்புறம் முழுத் திரை"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"மேலே 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"மேலே 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"மீண்டும் தொடங்கு"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"மீண்டும் காட்டாதே"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"இந்த ஆப்ஸை நகர்த்த\nஇருமுறை தட்டவும்"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸைப் பெரிதாக்கும்"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை மீட்டெடுக்கும்"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸைச் சிறிதாக்கும்"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை மூடும்"</string>
<string name="back_button_text" msgid="1469718707134137085">"பின்செல்லும்"</string>
<string name="handle_text" msgid="4419667835599523257">"ஆப்ஸ் ஹேண்டில்"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"சாளரத்தை இடதுபுறமாக அளவு மாற்றும்"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"சாளரத்தை வலதுபுறமாக அளவு மாற்றும்"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"சாளரத்தின் அளவைப் பெரிதாக்கும்/மீட்டெடுக்கும்"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ஆப்ஸ் சாளரத்தின் அளவைப் பெரிதாக்கும்"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"சாளரத்தின் அளவை மீட்டெடுக்கும்"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ஆப்ஸ் சாளரத்தைச் சிறிதாக்கும்"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ஆப்ஸ் சாளரத்தை மூடும்"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"இயல்பாக அமைப்புகளைத் திறக்கும்"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"இந்த ஆப்ஸில் வலை இணைப்புகளைத் திறக்கும் வழிமுறையைத் தேர்வுசெய்யுங்கள்"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ஆப்ஸில்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 96ce40abb477..e0930132e6f3 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ఎడమవైపు 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ఎడమవైపు 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"కుడివైపు ఫుల్-స్క్రీన్‌"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"పైన ఉన్న యాప్‌ను కింద ఉన్న యాప్‌తో మార్చండి"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ఎడమ వైపు ఉన్న యాప్‌ను కుడి వైపు ఉన్న యాప్‌తో మార్చండి"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ఎగువ ఫుల్-స్క్రీన్‌"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ఎగువ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ఎగువ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"రీస్టార్ట్ చేయండి"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"మళ్లీ చూపవద్దు"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ఈ యాప్‌ను తరలించడానికి\nడబుల్-ట్యాప్ చేయండి"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను పెద్దదిగా చేయండి"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను రీస్టోర్ చేయండి"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను చిన్నదిగా చేయండి"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g>‌ను మూసివేయండి"</string>
<string name="back_button_text" msgid="1469718707134137085">"వెనుకకు"</string>
<string name="handle_text" msgid="4419667835599523257">"యాప్ హ్యాండిల్"</string>
<string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"విండో ఎడమ వైపునకు సైజ్‌ను మార్చండి"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"విండో కుడి వైపునకు సైజ్‌ను మార్చండి"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"విండో సైజ్‌ను మ్యాగ్జిమైజ్ చేయండి లేదా రీస్టోర్ చేయండి"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"యాప్ విండో సైజ్‌ను పెద్దదిగా చేయండి"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"విండో సైజ్‌ను రీస్టోర్ చేయండి"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"యాప్ విండోను చిన్నదిగా చేయండి"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"యాప్ విండోను మూసివేయండి"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ఆటోమేటిక్ సెట్టింగ్‌ల ద్వారా తెరవండి"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ఈ యాప్‌నకు సంబంధించిన వెబ్ లింక్‌లను ఎలా తెరవాలో ఎంచుకోండి"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"యాప్‌లో"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index ad38be82a76a..f13de5b7846b 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Gawing 50% ang nasa kaliwa"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Gawing 30% ang nasa kaliwa"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"I-full screen ang nasa kanan"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Pagpalitin ang app sa itaas at ibaba"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Pagpalitin ang app sa kaliwa at kanan"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"I-full screen ang nasa itaas"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gawing 70% ang nasa itaas"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gawing 50% ang nasa itaas"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"I-restart"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Huwag nang ipakita ulit"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"I-double tap para\nilipat ang app na ito"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"I-maximize ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"I-restore ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"I-minimize ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Isara ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Bumalik"</string>
<string name="handle_text" msgid="4419667835599523257">"Handle ng app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"I-resize pakaliwa ang window"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"I-resize pakanan ang window"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"I-maximize o i-restore ang laki ng window"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"I-maximize ang laki ng window ng app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"I-restore ang laki ng window"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"I-minimize ang window ng app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Isara ang window ng app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Buksan sa pamamagitan ng mga default na setting"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Piliin kung paano magbukas ng web link para sa app na ito"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sa app"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 2bc0a960bbb5..61fae05cc71c 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Solda %50"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Solda %30"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Sağda tam ekran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Üstteki uygulamayı alttaki uygulamayla değiştir"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Soldaki uygulamayı sağdakiyle değiştir"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Üstte tam ekran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Üstte %70"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Üstte %50"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Yeniden başlat"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Bir daha gösterme"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Bu uygulamayı taşımak için\niki kez dokunun"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasını büyüt"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasını geri yükle"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasını küçült"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasını kapat"</string>
<string name="back_button_text" msgid="1469718707134137085">"Geri"</string>
<string name="handle_text" msgid="4419667835599523257">"Uygulama tanıtıcısı"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Pencereyi sola yeniden boyutlandır"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Pencereyi sağa yeniden boyutlandır"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Pencereyi ekranı kaplayacak şekilde büyüt veya önceki boyutuna döndür"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Uygulama penceresini ekranı kaplayacak şekilde büyüt"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Pencere boyutunu geri yükle"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Uygulama penceresini küçült"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Uygulama penceresini kapat"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Varsayılan olarak açma ayarları"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu uygulama için web bağlantılarının nasıl açılacağını seçin"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Uygulamada"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index c1aa82e472b1..ada82dfdc126 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ліве вікно на 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ліве вікно на 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Праве вікно на весь екран"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Поміняти місцями додатки зверху й знизу"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Поміняти місцями додатки ліворуч і праворуч"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхнє вікно на весь екран"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхнє вікно на 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхнє вікно на 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Перезапустити"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Більше не показувати"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Двічі торкніться, щоб\nперемістити цей додаток"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Розгорнути додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Відновити додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Згорнути додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Закрити додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Дескриптор додатка"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок додатка"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Змінити розмір вікна ліворуч"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Змінити розмір вікна праворуч"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Розгорнути вікно або відновити його розмір"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Розгорнути вікно додатка"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Відновити розмір вікна"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Згорнути вікно додатка"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Закрити вікно додатка"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Налаштування \"Відкривати за умовчанням\""</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Виберіть, як відкривати вебпосилання в цьому додатку"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У додатку"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 1afb48d7952c..ded104cfd718 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"بائیں %50"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"بائیں %30"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"دائیں فل اسکرین"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"اوپری ایپ کو نیچے کے ساتھ سویپ کریں"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"بائیں ایپ کو دائیں کے ساتھ سویپ کریں"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"بالائی فل اسکرین"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"اوپر %70"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"اوپر %50"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ری اسٹارٹ کریں"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوبارہ نہ دکھائیں"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"اس ایپ کو منتقل کرنے کیلئے\nدو بار تھپتھپائیں"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> بڑا کریں"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> کو بحال کریں"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> چھوٹا کریں"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> بند کریں"</string>
<string name="back_button_text" msgid="1469718707134137085">"پیچھے"</string>
<string name="handle_text" msgid="4419667835599523257">"ایپ ہینڈل"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"دائیں طرف ونڈو کا سائز تبدیل کریں"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ونڈو کا سائز بائیں طرف تبدیل کریں"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ونڈو کا سائز زیادہ سے زیادہ یا بحال کریں"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ایپ ونڈو سائز بڑا کریں"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ونڈو سائز بحال کریں"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ایپ ونڈو چھوٹا کریں"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ایپ ونڈو بند کریں"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"بطور ڈیفالٹ ترتیبات کھولیں"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"اس ایپ کے لیے ویب لنکس کھولنے کا طریقہ منتخب کریں"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ایپ میں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 04fd4290a89f..8a9dad029276 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Chapda 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Chapda 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"O‘ngda to‘liq ekran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Tepadagi ilovani pastkisi bilan almashtirish"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Chap ilovani oʻngdagisi bilan almashtirish"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Tepada to‘liq ekran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Tepada 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Tepada 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Qaytadan"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Boshqa chiqmasin"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Bu ilovani siljitish uchun\nikki marta bosing"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Yoyish: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Tiklash: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Kichraytirish: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Yopish: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Orqaga"</string>
<string name="handle_text" msgid="4419667835599523257">"Ilova identifikatori"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Oyna oʻlchamini chapga oʻzgartirish"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Oyna oʻlchamini oʻngga oʻzgartirish"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Oyna oʻlchamini kengaytirish yoki asliga qaytarish"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Ilova oynasini kattartirish"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Oyna hajmini tiklash"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Ilova oynasini kichraytirish"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Ilova oynasini yopish"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Birlamchi sozlamalar asosida ochish"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu ilovalardagi veb havolalar qanday ochilishini tanlang"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ilovada"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 169c2b787fa7..d6c8bc6173fb 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Trái 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Trái 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Toàn màn hình bên phải"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Hoán đổi ứng dụng ở trên cùng với ứng dụng ở dưới cùng"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Hoán đổi ứng dụng bên trái với ứng dụng bên phải"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Toàn màn hình phía trên"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Trên 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Trên 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Khởi động lại"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Không hiện lại"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Nhấn đúp để\ndi chuyển ứng dụng này"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Phóng to <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Khôi phục <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Thu nhỏ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Đóng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Quay lại"</string>
<string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Đổi kích thước và chuyển cửa sổ sang trái"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Đổi kích thước và chuyển cửa sổ sang phải"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Phóng to hoặc khôi phục kích thước cửa sổ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Phóng to kích thước cửa sổ ứng dụng"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Khôi phục kích thước cửa sổ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Thu nhỏ cửa sổ ứng dụng"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Đóng cửa sổ ứng dụng"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Mở các chế độ cài đặt theo mặc định"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Chọn cách mở đường liên kết trang web cho ứng dụng này"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Trong ứng dụng"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 942734ad0849..1009afc62f55 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左侧 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左侧 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右侧全屏"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"将顶部应用与底部应用互换"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"将左侧应用与右侧应用互换"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"顶部全屏"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"顶部 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"顶部 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"重启"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不再显示"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"点按两次\n即可移动此应用"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"将“<xliff:g id="APP_NAME">%1$s</xliff:g>”窗口最大化"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"恢复“<xliff:g id="APP_NAME">%1$s</xliff:g>”窗口大小"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"将“<xliff:g id="APP_NAME">%1$s</xliff:g>”窗口最小化"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"关闭“<xliff:g id="APP_NAME">%1$s</xliff:g>”"</string>
<string name="back_button_text" msgid="1469718707134137085">"返回"</string>
<string name="handle_text" msgid="4419667835599523257">"应用手柄"</string>
<string name="app_icon_text" msgid="2823268023931811747">"应用图标"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"调整窗口大小并贴靠左侧"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"调整窗口大小并贴靠右侧"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"将窗口最大化或恢复大小"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"将应用窗口最大化"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"恢复窗口大小"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"将应用窗口最小化"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"关闭应用窗口"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"默认打开设置"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"选择如何打开此应用中的网页链接"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在此应用内"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index f89792235c78..edd67c17fcf4 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左邊 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左邊 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右邊全螢幕"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"調換上下應用程式"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"調換左右應用程式"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"頂部全螢幕"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"頂部 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"頂部 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"輕按兩下\n即可移動此應用程式"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"將 <xliff:g id="APP_NAME">%1$s</xliff:g> 放到最大"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"還原 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"將 <xliff:g id="APP_NAME">%1$s</xliff:g> 縮到最細"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"閂 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"返去"</string>
<string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"將視窗移去左邊調整大小"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"將視窗移去右邊調整大小"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"將視窗放到最大或者還原視窗大小"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"將應用程式視窗放到最大"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"還原視窗大細"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"將應用程式視窗縮到最細"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"關閉應用程式視窗"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"採用預設設定打開"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"選擇此應用程式開啟網絡連結的方式"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在應用程式內"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 3c6abec3c08c..32d87f3f8ce6 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"以 50% 的螢幕空間顯示左側畫面"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"以 30% 的螢幕空間顯示左側畫面"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"以全螢幕顯示右側畫面"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"將頂端與底部的應用程式對調"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"將左側與右側的應用程式對調"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"以全螢幕顯示頂端畫面"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"以 70% 的螢幕空間顯示頂端畫面"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"以 50% 的螢幕空間顯示頂端畫面"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"輕觸兩下即可\n移動這個應用程式"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"最大化「<xliff:g id="APP_NAME">%1$s</xliff:g>」視窗"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"還原「<xliff:g id="APP_NAME">%1$s</xliff:g>」視窗"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"最小化「<xliff:g id="APP_NAME">%1$s</xliff:g>」視窗"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"關閉「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string>
<string name="back_button_text" msgid="1469718707134137085">"返回"</string>
<string name="handle_text" msgid="4419667835599523257">"應用程式控制代碼"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"調整應用程式視窗大小並向左貼齊"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"調整應用程式視窗大小並向右貼齊"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"將視窗最大化或還原大小"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"最大化應用程式視窗"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"還原視窗大小"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"最小化應用程式視窗"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"關閉應用程式視窗"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"開啟連結的預設設定"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"選擇如何開啟這個應用程式的網頁連結"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"使用應用程式"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index b304299a6c18..94f0d3476c5e 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kwesokunxele ngo-50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kwesokunxele ngo-30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Isikrini esigcwele esingakwesokudla"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Shintshanisa i-app ephezulu ngengaphansi"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Shintshanisa i-app engakwesokunxele naleyo engakwesokudla"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Isikrini esigcwele esiphezulu"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Okuphezulu okungu-70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Okuphezulu okungu-50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Qala kabusha"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ungabonisi futhi"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Thepha kabili ukuze\nuhambise le-app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Khulisa i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Buyisela i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Nciphisa i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Vala i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Emuva"</string>
<string name="handle_text" msgid="4419667835599523257">"Inkomba ye-App"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Shintsha usayizi wewindi ngakwesokunxele"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Shintsha usayizi wewindi ngakwesokudla"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Khulisa noma buyisela usayizi wewindi"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Khulisa usayizi wewindi le-app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Buyisela usayizi wewindi"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Nciphisa iwindi le-app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Vala iwindi le-app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Vula amasethingi ngokuzenzakalela"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Khetha indlela yokuvula amalinki ewebhu ale app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ku-app"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 32660e8fca27..60044ad51d83 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -619,13 +619,13 @@
<dimen name="desktop_mode_header_app_chip_ripple_inset_vertical">4dp</dimen>
<!-- The corner radius of the windowing actions pill buttons's ripple drawable -->
- <dimen name="desktop_mode_handle_menu_windowing_action_ripple_radius">24dp</dimen>
+ <dimen name="desktop_mode_handle_menu_icon_button_ripple_radius">24dp</dimen>
<!-- The horizontal/vertical inset to apply to the ripple drawable effect of windowing
actions pill central buttons -->
- <dimen name="desktop_mode_handle_menu_windowing_action_ripple_inset_base">2dp</dimen>
+ <dimen name="desktop_mode_handle_menu_icon_button_ripple_inset_base">2dp</dimen>
<!-- The horizontal/vertical vertical inset to apply to the ripple drawable effect of windowing
actions pill edge buttons -->
- <dimen name="desktop_mode_handle_menu_windowing_action_ripple_inset_shift">4dp</dimen>
+ <dimen name="desktop_mode_handle_menu_icon_button_ripple_inset_shift">4dp</dimen>
<!-- The corner radius of the minimize button's ripple drawable -->
<dimen name="desktop_mode_header_minimize_ripple_radius">18dp</dimen>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt
index 1a80b0f29aa9..362a5c5c3750 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt
@@ -111,47 +111,28 @@ class DragZoneFactory(
/** Updates all dimensions after a configuration change. */
fun onConfigurationUpdated() {
- dismissDragZoneSize =
- if (deviceConfig.isSmallTablet) {
- context.resolveDimension(R.dimen.drag_zone_dismiss_fold)
- } else {
- context.resolveDimension(R.dimen.drag_zone_dismiss_tablet)
- }
- bubbleDragZoneTabletSize = context.resolveDimension(R.dimen.drag_zone_bubble_tablet)
- bubbleDragZoneFoldableSize = context.resolveDimension(R.dimen.drag_zone_bubble_fold)
- fullScreenDragZoneWidth = context.resolveDimension(R.dimen.drag_zone_full_screen_width)
- fullScreenDragZoneHeight = context.resolveDimension(R.dimen.drag_zone_full_screen_height)
- desktopWindowDragZoneWidth =
- context.resolveDimension(R.dimen.drag_zone_desktop_window_width)
- desktopWindowDragZoneHeight =
- context.resolveDimension(R.dimen.drag_zone_desktop_window_height)
- desktopWindowFromExpandedViewDragZoneWidth =
- context.resolveDimension(R.dimen.drag_zone_desktop_window_expanded_view_width)
- desktopWindowFromExpandedViewDragZoneHeight =
- context.resolveDimension(R.dimen.drag_zone_desktop_window_expanded_view_height)
- splitFromBubbleDragZoneHeight =
- context.resolveDimension(R.dimen.drag_zone_split_from_bubble_height)
- splitFromBubbleDragZoneWidth =
- context.resolveDimension(R.dimen.drag_zone_split_from_bubble_width)
- hSplitFromExpandedViewDragZoneWidth =
- context.resolveDimension(R.dimen.drag_zone_h_split_from_expanded_view_width)
- vSplitFromExpandedViewDragZoneWidth =
- context.resolveDimension(R.dimen.drag_zone_v_split_from_expanded_view_width)
- vSplitFromExpandedViewDragZoneHeightTablet =
- context.resolveDimension(R.dimen.drag_zone_v_split_from_expanded_view_height_tablet)
- vSplitFromExpandedViewDragZoneHeightFoldTall =
- context.resolveDimension(R.dimen.drag_zone_v_split_from_expanded_view_height_fold_tall)
- vSplitFromExpandedViewDragZoneHeightFoldShort =
- context.resolveDimension(R.dimen.drag_zone_v_split_from_expanded_view_height_fold_short)
- fullScreenDropTargetPadding =
- context.resolveDimension(R.dimen.drop_target_full_screen_padding)
- desktopWindowDropTargetPaddingSmall =
- context.resolveDimension(R.dimen.drop_target_desktop_window_padding_small)
- desktopWindowDropTargetPaddingLarge =
- context.resolveDimension(R.dimen.drop_target_desktop_window_padding_large)
-
- // TODO b/393172431: Use the shared xml resources once we can easily access them from
+ // TODO b/396539130: Use the shared xml resources once we can easily access them from
// launcher
+ dismissDragZoneSize =
+ if (deviceConfig.isSmallTablet) 140.dpToPx() else 200.dpToPx()
+ bubbleDragZoneTabletSize = 200.dpToPx()
+ bubbleDragZoneFoldableSize = 140.dpToPx()
+ fullScreenDragZoneWidth = 512.dpToPx()
+ fullScreenDragZoneHeight = 44.dpToPx()
+ desktopWindowDragZoneWidth = 880.dpToPx()
+ desktopWindowDragZoneHeight = 300.dpToPx()
+ desktopWindowFromExpandedViewDragZoneWidth = 200.dpToPx()
+ desktopWindowFromExpandedViewDragZoneHeight = 350.dpToPx()
+ splitFromBubbleDragZoneHeight = 100.dpToPx()
+ splitFromBubbleDragZoneWidth = 60.dpToPx()
+ hSplitFromExpandedViewDragZoneWidth = 60.dpToPx()
+ vSplitFromExpandedViewDragZoneWidth = 200.dpToPx()
+ vSplitFromExpandedViewDragZoneHeightTablet = 285.dpToPx()
+ vSplitFromExpandedViewDragZoneHeightFoldTall = 150.dpToPx()
+ vSplitFromExpandedViewDragZoneHeightFoldShort = 100.dpToPx()
+ fullScreenDropTargetPadding = 20.dpToPx()
+ desktopWindowDropTargetPaddingSmall = 100.dpToPx()
+ desktopWindowDropTargetPaddingLarge = 130.dpToPx()
expandedViewDropTargetWidth = 364.dpToPx()
expandedViewDropTargetHeight = 578.dpToPx()
expandedViewDropTargetPaddingBottom = 108.dpToPx()
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
index 2bb6cf4ec3aa..73277310ffe4 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
@@ -20,6 +20,7 @@ import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
+import android.util.TypedValue
import android.view.View
import com.android.wm.shell.shared.R
@@ -37,14 +38,21 @@ class DropTargetView(context: Context) : View(context) {
private val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = context.getColor(com.android.internal.R.color.materialColorPrimaryContainer)
style = Paint.Style.STROKE
- strokeWidth = context.resources.getDimensionPixelSize(R.dimen.drop_target_stroke).toFloat()
+ strokeWidth = 1.dpToPx()
}
- private val cornerRadius = context.resources.getDimensionPixelSize(
- R.dimen.drop_target_radius).toFloat()
+ private val cornerRadius = 28.dpToPx()
private val rect = RectF(0f, 0f, 0f, 0f)
+ // TODO b/396539130: Use shared xml resources once we can access them in launcher
+ private fun Int.dpToPx() =
+ TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP,
+ this.toFloat(),
+ context.resources.displayMetrics
+ )
+
override fun onDraw(canvas: Canvas) {
canvas.save()
canvas.drawRoundRect(rect, cornerRadius, cornerRadius, rectPaint)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
index 5018fdb615da..8e78686ac13d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
@@ -83,7 +83,11 @@ public class SizeChangeAnimation {
private static final int ANIMATION_RESOLUTION = 1000;
public SizeChangeAnimation(Rect startBounds, Rect endBounds) {
- mAnimation = buildContainerAnimation(startBounds, endBounds);
+ this(startBounds, endBounds, 1f);
+ }
+
+ public SizeChangeAnimation(Rect startBounds, Rect endBounds, float initialScale) {
+ mAnimation = buildContainerAnimation(startBounds, endBounds, initialScale);
mSnapshotAnim = buildSnapshotAnimation(startBounds, endBounds);
}
@@ -167,7 +171,8 @@ public class SizeChangeAnimation {
}
/** Animation for the whole container (snapshot is inside this container). */
- private static AnimationSet buildContainerAnimation(Rect startBounds, Rect endBounds) {
+ private static AnimationSet buildContainerAnimation(Rect startBounds, Rect endBounds,
+ float initialScale) {
final long duration = ANIMATION_RESOLUTION;
boolean growing = endBounds.width() - startBounds.width()
+ endBounds.height() - startBounds.height() >= 0;
@@ -180,15 +185,27 @@ public class SizeChangeAnimation {
final Animation scaleAnim = new ScaleAnimation(startScaleX, 1, startScaleY, 1);
scaleAnim.setDuration(scalePeriod);
+ long scaleStartOffset = 0;
if (!growing) {
- scaleAnim.setStartOffset(duration - scalePeriod);
+ scaleStartOffset = duration - scalePeriod;
}
+ scaleAnim.setStartOffset(scaleStartOffset);
animSet.addAnimation(scaleAnim);
+
+ if (initialScale != 1f) {
+ final Animation initialScaleAnim = new ScaleAnimation(initialScale, 1f, initialScale,
+ 1f);
+ initialScaleAnim.setDuration(scalePeriod);
+ initialScaleAnim.setStartOffset(scaleStartOffset);
+ animSet.addAnimation(initialScaleAnim);
+ }
+
final Animation translateAnim = new TranslateAnimation(startBounds.left,
endBounds.left, startBounds.top, endBounds.top);
translateAnim.setDuration(duration);
animSet.addAnimation(translateAnim);
Rect startClip = new Rect(startBounds);
+ startClip.scale(initialScale);
Rect endClip = new Rect(endBounds);
startClip.offsetTo(0, 0);
endClip.offsetTo(0, 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index d1c7f7d7dcad..80b65d025399 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -28,6 +28,7 @@ import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_PREDICTIVE_BACK_HOME;
+import static com.android.systemui.Flags.predictiveBackDelayTransition;
import static com.android.window.flags.Flags.unifyBackNavigationTransition;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
@@ -431,6 +432,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
@VisibleForTesting
public void onThresholdCrossed() {
mThresholdCrossed = true;
+ BackTouchTracker activeTracker = getActiveTracker();
+ if (predictiveBackDelayTransition() && activeTracker != null && mActiveCallback == null
+ && mBackGestureStarted) {
+ startBackNavigation(activeTracker);
+ }
// There was no focus window when calling startBackNavigation, still pilfer pointers so
// the next focus window won't receive motion events.
if (mBackNavigationInfo == null && mReceivedNullNavigationInfo) {
@@ -488,9 +494,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (swipeEdge == EDGE_NONE) {
// start animation immediately for non-gestural sources (without ACTION_MOVE
// events)
- mThresholdCrossed = true;
+ if (!predictiveBackDelayTransition()) {
+ mThresholdCrossed = true;
+ }
mPointersPilfered = true;
onGestureStarted(touchX, touchY, swipeEdge);
+ if (predictiveBackDelayTransition()) {
+ onThresholdCrossed();
+ }
mShouldStartOnNextMoveEvent = false;
} else {
mShouldStartOnNextMoveEvent = true;
@@ -544,14 +555,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mPostCommitAnimationInProgress = false;
mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
startSystemAnimation();
- } else if (touchTracker == mCurrentTracker) {
- // Only start the back navigation if no other gesture is being processed. Otherwise,
- // the back navigation will fall back to legacy back event injection.
- startBackNavigation(mCurrentTracker);
+ } else if (!predictiveBackDelayTransition()) {
+ startBackNavigation(touchTracker);
}
}
private void startBackNavigation(@NonNull BackTouchTracker touchTracker) {
+ if (touchTracker != mCurrentTracker) {
+ // Only start the back navigation if no other gesture is being processed. Otherwise,
+ // the back navigation will fall back to legacy back event injection.
+ return;
+ }
try {
startLatencyTracking();
if (mBackAnimationAdapter != null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
index 338ffe76e6ea..d5f2dbdbf5f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
@@ -30,6 +30,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.TaskInfo;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.Slog;
@@ -155,28 +156,26 @@ public class BubbleTransitions {
* Information about the task when it is being dragged to a bubble
*/
public static class DragData {
- private final Rect mBounds;
private final WindowContainerTransaction mPendingWct;
private final boolean mReleasedOnLeft;
+ private final float mTaskScale;
+ private final float mCornerRadius;
+ private final PointF mDragPosition;
/**
- * @param bounds bounds of the dragged task when the drag was released
- * @param wct pending operations to be applied when finishing the drag
* @param releasedOnLeft true if the bubble was released in the left drop target
+ * @param taskScale the scale of the task when it was dragged to bubble
+ * @param cornerRadius the corner radius of the task when it was dragged to bubble
+ * @param dragPosition the position of the task when it was dragged to bubble
+ * @param wct pending operations to be applied when finishing the drag
*/
- public DragData(@Nullable Rect bounds, @Nullable WindowContainerTransaction wct,
- boolean releasedOnLeft) {
- mBounds = bounds;
+ public DragData(boolean releasedOnLeft, float taskScale, float cornerRadius,
+ @Nullable PointF dragPosition, @Nullable WindowContainerTransaction wct) {
mPendingWct = wct;
mReleasedOnLeft = releasedOnLeft;
- }
-
- /**
- * @return bounds of the dragged task when the drag was released
- */
- @Nullable
- public Rect getBounds() {
- return mBounds;
+ mTaskScale = taskScale;
+ mCornerRadius = cornerRadius;
+ mDragPosition = dragPosition != null ? dragPosition : new PointF(0, 0);
}
/**
@@ -193,6 +192,27 @@ public class BubbleTransitions {
public boolean isReleasedOnLeft() {
return mReleasedOnLeft;
}
+
+ /**
+ * @return the scale of the task when it was dragged to bubble
+ */
+ public float getTaskScale() {
+ return mTaskScale;
+ }
+
+ /**
+ * @return the corner radius of the task when it was dragged to bubble
+ */
+ public float getCornerRadius() {
+ return mCornerRadius;
+ }
+
+ /**
+ * @return position of the task when it was dragged to bubble
+ */
+ public PointF getDragPosition() {
+ return mDragPosition;
+ }
}
/**
@@ -347,29 +367,27 @@ public class BubbleTransitions {
}
mFinishCb = finishCallback;
- if (mDragData != null && mDragData.getBounds() != null) {
- // Override start bounds with the dragged task bounds
- mStartBounds.set(mDragData.getBounds());
+ if (mDragData != null) {
+ mStartBounds.offsetTo((int) mDragData.getDragPosition().x,
+ (int) mDragData.getDragPosition().y);
+ startTransaction.setScale(mSnapshot, mDragData.getTaskScale(),
+ mDragData.getTaskScale());
+ startTransaction.setCornerRadius(mSnapshot, mDragData.getCornerRadius());
}
// Now update state (and talk to launcher) in parallel with snapshot stuff
mBubbleData.notificationEntryUpdated(mBubble, /* suppressFlyout= */ true,
/* showInShade= */ false);
+ final int left = mStartBounds.left - info.getRoot(0).getOffset().x;
+ final int top = mStartBounds.top - info.getRoot(0).getOffset().y;
+ startTransaction.setPosition(mTaskLeash, left, top);
startTransaction.show(mSnapshot);
// Move snapshot to root so that it remains visible while task is moved to taskview
startTransaction.reparent(mSnapshot, info.getRoot(0).getLeash());
- startTransaction.setPosition(mSnapshot,
- mStartBounds.left - info.getRoot(0).getOffset().x,
- mStartBounds.top - info.getRoot(0).getOffset().y);
+ startTransaction.setPosition(mSnapshot, left, top);
startTransaction.setLayer(mSnapshot, Integer.MAX_VALUE);
- BubbleBarExpandedView bbev = mBubble.getBubbleBarExpandedView();
- if (bbev != null) {
- // Corners get reset during the animation. Add them back
- startTransaction.setCornerRadius(mSnapshot, bbev.getRestingCornerRadius());
- }
-
startTransaction.apply();
mTaskViewTransitions.onExternalDone(transition);
@@ -416,6 +434,8 @@ public class BubbleTransitions {
private void playAnimation(boolean animate) {
final TaskViewTaskController tv = mBubble.getTaskView().getController();
final SurfaceControl.Transaction startT = new SurfaceControl.Transaction();
+ // Set task position to 0,0 as it will be placed inside the TaskView
+ startT.setPosition(mTaskLeash, 0, 0);
mTaskViewTransitions.prepareOpenAnimation(tv, true /* new */, startT, mFinishT,
(ActivityManager.RunningTaskInfo) mTaskInfo, mTaskLeash, mFinishWct);
@@ -424,10 +444,12 @@ public class BubbleTransitions {
}
if (animate) {
- mLayerView.animateConvert(startT, mStartBounds, mSnapshot, mTaskLeash, () -> {
- mFinishCb.onTransitionFinished(mFinishWct);
- mFinishCb = null;
- });
+ float startScale = mDragData != null ? mDragData.getTaskScale() : 1f;
+ mLayerView.animateConvert(startT, mStartBounds, startScale, mSnapshot, mTaskLeash,
+ () -> {
+ mFinishCb.onTransitionFinished(mFinishWct);
+ mFinishCb = null;
+ });
} else {
startT.apply();
mFinishCb.onTransitionFinished(mFinishWct);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 52f20646fb4a..fa22a3961002 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -580,6 +580,7 @@ public class BubbleBarAnimationHelper {
public void animateConvert(BubbleViewProvider expandedBubble,
@NonNull SurfaceControl.Transaction startT,
@NonNull Rect origBounds,
+ float origScale,
@NonNull SurfaceControl snapshot,
@NonNull SurfaceControl taskLeash,
@Nullable Runnable afterAnimation) {
@@ -599,7 +600,7 @@ public class BubbleBarAnimationHelper {
new SizeChangeAnimation(
new Rect(origBounds.left - position.x, origBounds.top - position.y,
origBounds.right - position.x, origBounds.bottom - position.y),
- new Rect(0, 0, size.getWidth(), size.getHeight()));
+ new Rect(0, 0, size.getWidth(), size.getHeight()), origScale);
sca.initialize(bbev, taskLeash, snapshot, startT);
Animator a = sca.buildViewAnimator(bbev, tvSf, snapshot, /* onFinish */ (va) -> {
@@ -614,6 +615,7 @@ public class BubbleBarAnimationHelper {
bbev.setSurfaceZOrderedOnTop(true);
a.setDuration(EXPANDED_VIEW_ANIMATE_TO_REST_DURATION);
+ a.setInterpolator(Interpolators.EMPHASIZED);
a.start();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 99082f18492c..6c840f020f90 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -423,13 +423,13 @@ public class BubbleBarLayerView extends FrameLayout
* @param startT A transaction with first-frame work. this *will* be applied here!
*/
public void animateConvert(@NonNull SurfaceControl.Transaction startT,
- @NonNull Rect startBounds, @NonNull SurfaceControl snapshot, SurfaceControl taskLeash,
- Runnable animFinish) {
+ @NonNull Rect startBounds, float startScale, @NonNull SurfaceControl snapshot,
+ SurfaceControl taskLeash, Runnable animFinish) {
if (!mIsExpanded || mExpandedBubble == null) {
throw new IllegalStateException("Can't animateExpand without expanded state");
}
- mAnimationHelper.animateConvert(mExpandedBubble, startT, startBounds, snapshot, taskLeash,
- animFinish);
+ mAnimationHelper.animateConvert(mExpandedBubble, startT, startBounds, startScale, snapshot,
+ taskLeash, animFinish);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
index 214e6ad455a1..aeef211ae3f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
@@ -143,6 +143,9 @@ public class PipBoundsState {
*/
public final Rect mCachedLauncherShelfHeightKeepClearArea = new Rect();
+ private final List<OnPipComponentChangedListener> mOnPipComponentChangedListeners =
+ new ArrayList<>();
+
// the size of the current bounds relative to the max size spec
private float mBoundsScale;
@@ -156,9 +159,7 @@ public class PipBoundsState {
// Update the relative proportion of the bounds compared to max possible size. Max size
// spec takes the aspect ratio of the bounds into account, so both width and height
// scale by the same factor.
- addPipExclusionBoundsChangeCallback((bounds) -> {
- updateBoundsScale();
- });
+ addPipExclusionBoundsChangeCallback((bounds) -> updateBoundsScale());
}
/** Reloads the resources. */
@@ -341,11 +342,14 @@ public class PipBoundsState {
/** Set the last {@link ComponentName} to enter PIP mode. */
public void setLastPipComponentName(@Nullable ComponentName lastPipComponentName) {
final boolean changed = !Objects.equals(mLastPipComponentName, lastPipComponentName);
+ if (!changed) return;
+ clearReentryState();
+ setHasUserResizedPip(false);
+ setHasUserMovedPip(false);
+ final ComponentName oldComponentName = mLastPipComponentName;
mLastPipComponentName = lastPipComponentName;
- if (changed) {
- clearReentryState();
- setHasUserResizedPip(false);
- setHasUserMovedPip(false);
+ for (OnPipComponentChangedListener listener : mOnPipComponentChangedListeners) {
+ listener.onPipComponentChanged(oldComponentName, mLastPipComponentName);
}
}
@@ -616,6 +620,21 @@ public class PipBoundsState {
}
}
+ /** Adds callback to listen on component change. */
+ public void addOnPipComponentChangedListener(@NonNull OnPipComponentChangedListener listener) {
+ if (!mOnPipComponentChangedListeners.contains(listener)) {
+ mOnPipComponentChangedListeners.add(listener);
+ }
+ }
+
+ /** Removes callback to listen on component change. */
+ public void removeOnPipComponentChangedListener(
+ @NonNull OnPipComponentChangedListener listener) {
+ if (mOnPipComponentChangedListeners.contains(listener)) {
+ mOnPipComponentChangedListeners.remove(listener);
+ }
+ }
+
public LauncherState getLauncherState() {
return mLauncherState;
}
@@ -695,7 +714,7 @@ public class PipBoundsState {
* Represents the state of pip to potentially restore upon reentry.
*/
@VisibleForTesting
- public static final class PipReentryState {
+ static final class PipReentryState {
private static final String TAG = PipReentryState.class.getSimpleName();
private final float mSnapFraction;
@@ -722,6 +741,22 @@ public class PipBoundsState {
}
}
+ /**
+ * Listener interface for PiP component change, i.e. the app in pip mode changes
+ * TODO: Move this out of PipBoundsState once pip1 is deprecated.
+ */
+ public interface OnPipComponentChangedListener {
+ /**
+ * Callback when the component in pip mode changes.
+ * @param oldPipComponent previous component in pip mode,
+ * {@code null} if this is the very first time PiP appears.
+ * @param newPipComponent new component that enters pip mode.
+ */
+ void onPipComponentChanged(
+ @Nullable ComponentName oldPipComponent,
+ @NonNull ComponentName newPipComponent);
+ }
+
/** Dumps internal state. */
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
index 01fd3442f604..453ca167557a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
@@ -20,9 +20,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import android.window.DesktopExperienceFlags;
+import android.window.DesktopModeFlags;
import android.window.DisplayAreaInfo;
-import com.android.window.flags.Flags;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
@@ -48,18 +49,23 @@ public class PipDesktopState {
/**
* Returns whether PiP in Desktop Windowing is enabled by checking the following:
- * - Desktop Windowing in PiP flag is enabled
+ * - PiP in Desktop Windowing flag is enabled
* - DesktopUserRepositories is injected
* - DragToDesktopTransitionHandler is injected
*/
public boolean isDesktopWindowingPipEnabled() {
- return Flags.enableDesktopWindowingPip() && mDesktopUserRepositoriesOptional.isPresent()
+ return DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()
+ && mDesktopUserRepositoriesOptional.isPresent()
&& mDragToDesktopTransitionHandlerOptional.isPresent();
}
- /** Returns whether PiP in Connected Displays is enabled by checking the flag. */
+ /**
+ * Returns whether PiP in Connected Displays is enabled by checking the following:
+ * - PiP in Connected Displays flag is enabled
+ * - PiP2 flag is enabled
+ */
public boolean isConnectedDisplaysPipEnabled() {
- return DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue();
+ return DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue() && Flags.enablePip2();
}
/** Returns whether the display with the PiP task is in freeform windowing mode. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index e20a3d839def..fec1f56c76bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -1466,11 +1466,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
// Freeze the configuration size with offset to prevent app get a configuration
// changed or relaunch. This is required to make sure client apps will calculate
// insets properly after layout shifted.
- if (mTargetYOffset == 0) {
- mSplitLayoutHandler.setLayoutOffsetTarget(0, 0, SplitLayout.this);
- } else {
- mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset, SplitLayout.this);
- }
+ mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset, SplitLayout.this);
}
// Make {@link DividerView} non-interactive while IME showing in split mode. Listen to
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 6b7f311daa7c..0c654616507d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -36,6 +36,7 @@ import android.os.Handler;
import android.os.UserManager;
import android.view.Choreographer;
import android.view.IWindowManager;
+import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.DesktopModeFlags;
@@ -93,6 +94,7 @@ import com.android.wm.shell.desktopmode.DesktopModeDragAndDropTransitionHandler;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeKeyGestureHandler;
import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
+import com.android.wm.shell.desktopmode.DesktopModeMoveToDisplayTransitionHandler;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
import com.android.wm.shell.desktopmode.DesktopTaskChangeListener;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -448,7 +450,8 @@ public abstract class WMShellModule {
Optional<DesktopImmersiveController> desktopImmersiveController,
WindowDecorViewModel windowDecorViewModel,
Optional<TaskChangeListener> taskChangeListener,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ Optional<DesksTransitionObserver> desksTransitionObserver) {
return new FreeformTaskTransitionObserver(
context,
shellInit,
@@ -456,7 +459,8 @@ public abstract class WMShellModule {
desktopImmersiveController,
windowDecorViewModel,
taskChangeListener,
- focusTransitionObserver);
+ focusTransitionObserver,
+ desksTransitionObserver);
}
@WMSingleton
@@ -769,10 +773,11 @@ public abstract class WMShellModule {
Optional<BubbleController> bubbleController,
OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver,
DesksOrganizer desksOrganizer,
- DesksTransitionObserver desksTransitionObserver,
+ Optional<DesksTransitionObserver> desksTransitionObserver,
UserProfileContexts userProfileContexts,
DesktopModeCompatPolicy desktopModeCompatPolicy,
- DragToDisplayTransitionHandler dragToDisplayTransitionHandler) {
+ DragToDisplayTransitionHandler dragToDisplayTransitionHandler,
+ DesktopModeMoveToDisplayTransitionHandler moveToDisplayTransitionHandler) {
return new DesktopTasksController(
context,
shellInit,
@@ -809,10 +814,11 @@ public abstract class WMShellModule {
bubbleController,
overviewToDesktopTransitionObserver,
desksOrganizer,
- desksTransitionObserver,
+ desksTransitionObserver.get(),
userProfileContexts,
desktopModeCompatPolicy,
- dragToDisplayTransitionHandler);
+ dragToDisplayTransitionHandler,
+ moveToDisplayTransitionHandler);
}
@WMSingleton
@@ -869,12 +875,12 @@ public abstract class WMShellModule {
Transitions transitions,
@DynamicOverride DesktopUserRepositories desktopUserRepositories,
ShellTaskOrganizer shellTaskOrganizer,
+ DesksOrganizer desksOrganizer,
InteractionJankMonitor interactionJankMonitor,
@ShellMainThread Handler handler) {
int maxTaskLimit = DesktopModeStatus.getMaxTaskLimit(context);
if (!DesktopModeStatus.canEnterDesktopMode(context)
- || !ENABLE_DESKTOP_WINDOWING_TASK_LIMIT.isTrue()
- || maxTaskLimit <= 0) {
+ || !ENABLE_DESKTOP_WINDOWING_TASK_LIMIT.isTrue()) {
return Optional.empty();
}
return Optional.of(
@@ -882,7 +888,8 @@ public abstract class WMShellModule {
transitions,
desktopUserRepositories,
shellTaskOrganizer,
- maxTaskLimit,
+ desksOrganizer,
+ maxTaskLimit <= 0 ? null : maxTaskLimit,
interactionJankMonitor,
context,
handler));
@@ -950,6 +957,12 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
+ static DesktopModeMoveToDisplayTransitionHandler provideMoveToDisplayTransitionHandler() {
+ return new DesktopModeMoveToDisplayTransitionHandler(new SurfaceControl.Transaction());
+ }
+
+ @WMSingleton
+ @Provides
static Optional<DesktopModeKeyGestureHandler> provideDesktopModeKeyGestureHandler(
Context context,
Optional<DesktopModeWindowDecorViewModel> desktopModeWindowDecorViewModel,
@@ -1194,7 +1207,6 @@ public abstract class WMShellModule {
Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
Optional<BackAnimationController> backAnimationController,
DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
- @NonNull DesksTransitionObserver desksTransitionObserver,
ShellInit shellInit) {
return desktopUserRepositories.flatMap(
repository ->
@@ -1207,17 +1219,21 @@ public abstract class WMShellModule {
desktopMixedTransitionHandler.get(),
backAnimationController.get(),
desktopWallpaperActivityTokenProvider,
- desksTransitionObserver,
shellInit)));
}
@WMSingleton
@Provides
- static DesksTransitionObserver provideDesksTransitionObserver(
- @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories,
+ static Optional<DesksTransitionObserver> provideDesksTransitionObserver(
+ Context context,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
@NonNull DesksOrganizer desksOrganizer
) {
- return new DesksTransitionObserver(desktopUserRepositories, desksOrganizer);
+ if (DesktopModeStatus.canEnterDesktopMode(context)) {
+ return Optional.of(
+ new DesksTransitionObserver(desktopUserRepositories, desksOrganizer));
+ }
+ return Optional.empty();
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt
new file mode 100644
index 000000000000..fbf170f13a40
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wm.shell.desktopmode
+
+import android.animation.Animator
+import android.animation.ValueAnimator
+import android.os.IBinder
+import android.view.Choreographer
+import android.view.SurfaceControl
+import android.window.TransitionInfo
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import com.android.wm.shell.shared.animation.Interpolators
+import com.android.wm.shell.transition.Transitions
+import kotlin.time.Duration.Companion.milliseconds
+
+/**
+ * Transition handler for moving a window to a different display.
+ */
+class DesktopModeMoveToDisplayTransitionHandler(
+ private val animationTransaction: SurfaceControl.Transaction
+) : Transitions.TransitionHandler {
+
+ override fun handleRequest(
+ transition: IBinder,
+ request: TransitionRequestInfo,
+ ): WindowContainerTransaction? = null
+
+ override fun startAnimation(
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: Transitions.TransitionFinishCallback,
+ ): Boolean {
+ val change = info.changes.find { it.startDisplayId != it.endDisplayId } ?: return false
+ ValueAnimator.ofFloat(0f, 1f)
+ .apply {
+ duration = ANIM_DURATION.inWholeMilliseconds
+ interpolator = Interpolators.LINEAR
+ addUpdateListener { animation ->
+ animationTransaction
+ .setAlpha(change.leash, animation.animatedValue as Float)
+ .setFrameTimeline(Choreographer.getInstance().vsyncId)
+ .apply()
+ }
+ addListener(
+ object : Animator.AnimatorListener {
+ override fun onAnimationStart(animation: Animator) {
+ val endBounds = change.endAbsBounds
+ startTransaction
+ .setPosition(
+ change.leash,
+ endBounds.left.toFloat(),
+ endBounds.top.toFloat(),
+ )
+ .setWindowCrop(change.leash, endBounds.width(), endBounds.height())
+ .apply()
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ finishTransaction.apply()
+ finishCallback.onTransitionFinished(null)
+ }
+
+ override fun onAnimationCancel(animation: Animator) {
+ finishTransaction.apply()
+ finishCallback.onTransitionFinished(null)
+ }
+
+ override fun onAnimationRepeat(animation: Animator) = Unit
+ }
+ )
+ }
+ .start()
+ return true
+ }
+
+ private companion object {
+ val ANIM_DURATION = 100.milliseconds
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 56de48daf810..70539902f651 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -103,6 +103,10 @@ public class DesktopModeVisualIndicator {
return null;
}
}
+
+ private static boolean isDragToDesktopStartState(DragStartState startState) {
+ return startState == FROM_FULLSCREEN || startState == FROM_SPLIT;
+ }
}
private final VisualIndicatorViewContainer mVisualIndicatorViewContainer;
@@ -125,7 +129,12 @@ public class DesktopModeVisualIndicator {
@Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider,
SnapEventHandler snapEventHandler) {
SurfaceControl.Builder builder = new SurfaceControl.Builder();
- taskDisplayAreaOrganizer.attachToDisplayArea(taskInfo.displayId, builder);
+ if (!DragStartState.isDragToDesktopStartState(dragStartState)
+ || !DesktopModeFlags.ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX.isTrue()) {
+ // In the DragToDesktop transition we attach the indicator to the transition root once
+ // that is available - for all other cases attach the indicator here.
+ taskDisplayAreaOrganizer.attachToDisplayArea(taskInfo.displayId, builder);
+ }
mVisualIndicatorViewContainer = new VisualIndicatorViewContainer(
DesktopModeFlags.ENABLE_DESKTOP_INDICATOR_IN_SEPARATE_THREAD_BUGFIX.isTrue()
? desktopExecutor : mainExecutor,
@@ -159,6 +168,18 @@ public class DesktopModeVisualIndicator {
mVisualIndicatorViewContainer.releaseVisualIndicator();
}
+ /** Reparent the visual indicator to {@code newParent}. */
+ void reparentLeash(SurfaceControl.Transaction t, SurfaceControl newParent) {
+ mVisualIndicatorViewContainer.reparentLeash(t, newParent);
+ }
+
+ /** Start the fade-in animation. */
+ void fadeInIndicator() {
+ mVisualIndicatorViewContainer.fadeInIndicator(
+ mDisplayController.getDisplayLayout(mTaskInfo.displayId), mCurrentType,
+ mTaskInfo.displayId);
+ }
+
/**
* Based on the coordinates of the current drag event, determine which indicator type we should
* display, including no visible indicator.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 8c2748742595..f64bd757de3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -235,6 +235,10 @@ class DesktopRepository(
/** Returns the default desk in the given display. */
private fun getDefaultDesk(displayId: Int): Desk? = desktopData.getDefaultDesk(displayId)
+ /** Returns whether the given desk is active in its display. */
+ fun isDeskActive(deskId: Int): Boolean =
+ desktopData.getAllActiveDesks().any { desk -> desk.deskId == deskId }
+
/** Sets the given desk as the active one in the given display. */
fun setActiveDesk(displayId: Int, deskId: Int) {
logD("setActiveDesk for displayId=%d and deskId=%d", displayId, deskId)
@@ -485,7 +489,7 @@ class DesktopRepository(
fun getExpandedTasksOrdered(displayId: Int): List<Int> =
getFreeformTasksInZOrder(displayId).filter { !isMinimizedTask(it) }
- @VisibleForTesting
+ /** Returns all active non-minimized tasks for [deskId] ordered from top to bottom. */
fun getExpandedTasksIdsInDeskOrdered(deskId: Int): List<Int> =
getFreeformTasksIdsInDeskInZOrder(deskId).filter { !isMinimizedTask(it) }
@@ -733,7 +737,8 @@ class DesktopRepository(
desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId = null
}
- private fun notifyVisibleTaskListeners(displayId: Int, visibleTasksCount: Int) {
+ @VisibleForTesting
+ public fun notifyVisibleTaskListeners(displayId: Int, visibleTasksCount: Int) {
visibleTasksListeners.forEach { (listener, executor) ->
executor.execute { listener.onTasksVisibilityChanged(displayId, visibleTasksCount) }
}
@@ -915,6 +920,7 @@ class DesktopRepository(
val wasActive = desktopData.getActiveDesk(desk.displayId)?.deskId == desk.deskId
val activeTasks = ArraySet(desk.activeTasks)
desktopData.remove(desk.deskId)
+ notifyVisibleTaskListeners(desk.displayId, getVisibleTaskCount(displayId = desk.displayId))
deskChangeListeners.forEach { (listener, executor) ->
executor.execute {
if (wasActive) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
index 70a648f57125..e04d14459284 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
@@ -53,24 +53,12 @@ class DesktopTaskChangeListener(private val desktopUserRepositories: DesktopUser
// Case 1: When the task change is from a task in the desktop repository which is now
// fullscreen,
// remove the task from the desktop repository since it is no longer a freeform task.
- if (!isFreeformTask(taskInfo)) {
- if (desktopRepository.isActiveTask(taskInfo.taskId)) {
- desktopRepository.removeTask(taskInfo.displayId, taskInfo.taskId)
- }
- } else { // Task change is a freeform task
- if (!desktopRepository.isActiveTask(taskInfo.taskId)) {
- // Case 2: When the task change is a freeform visible task, but the task is not
- // yet active in the desktop repository, adds task to desktop repository.
- desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible)
- } else {
- // Case 3: When the task change is a freeform task which already exists as an active
- // task in the desktop repository, updates the task state.
- desktopRepository.updateTask(
- taskInfo.displayId,
- taskInfo.taskId,
- taskInfo.isVisible,
- )
- }
+ if (!isFreeformTask(taskInfo) && desktopRepository.isActiveTask(taskInfo.taskId)) {
+ desktopRepository.removeTask(taskInfo.displayId, taskInfo.taskId)
+ } else if (isFreeformTask(taskInfo)) {
+ // If the task is already active in the repository, then moves task to the front,
+ // else adds the task.
+ desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible)
}
}
@@ -109,7 +97,7 @@ class DesktopTaskChangeListener(private val desktopUserRepositories: DesktopUser
desktopUserRepositories.getProfile(taskInfo.userId)
if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
logD("onTaskMovingToBack for taskId=%d, displayId=%d", taskInfo.taskId, taskInfo.displayId)
- // TODO: b/367268953 - Connect this with DesktopRepository.
+ desktopRepository.updateTask(taskInfo.displayId, taskInfo.taskId, /* isVisible= */ false)
}
override fun onTaskClosing(taskInfo: RunningTaskInfo) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 9cacb0c7d2b8..f67323bb7eb1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -22,6 +22,7 @@ import android.app.ActivityManager.RunningTaskInfo
import android.app.ActivityOptions
import android.app.KeyguardManager
import android.app.PendingIntent
+import android.app.TaskInfo
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -47,6 +48,7 @@ import android.view.DragEvent
import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
+import android.view.WindowManager
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_NONE
@@ -208,6 +210,7 @@ class DesktopTasksController(
private val userProfileContexts: UserProfileContexts,
private val desktopModeCompatPolicy: DesktopModeCompatPolicy,
private val dragToDisplayTransitionHandler: DragToDisplayTransitionHandler,
+ private val moveToDisplayTransitionHandler: DesktopModeMoveToDisplayTransitionHandler,
) :
RemoteCallable<DesktopTasksController>,
Transitions.TransitionHandler,
@@ -520,7 +523,8 @@ class DesktopTasksController(
return false
}
logV("moveBackgroundTaskToDesktop with taskId=%d", taskId)
- val taskIdToMinimize = bringDesktopAppsToFront(task.displayId, wct, taskId)
+ val deskId = getDefaultDeskId(task.displayId)
+ val runOnTransitStart = addDeskActivationChanges(deskId, wct, task)
val exitResult =
desktopImmersiveController.exitImmersiveIfApplicable(
wct = wct,
@@ -549,9 +553,7 @@ class DesktopTasksController(
desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
FREEFORM_ANIMATION_DURATION
)
- taskIdToMinimize?.let {
- addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT)
- }
+ runOnTransitStart?.invoke(transition)
exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
return true
}
@@ -639,6 +641,7 @@ class DesktopTasksController(
dragToDesktopTransitionHandler.startDragToDesktopTransition(
taskInfo,
dragToDesktopValueAnimator,
+ visualIndicator,
)
}
@@ -959,10 +962,13 @@ class DesktopTasksController(
.apply { launchWindowingMode = WINDOWING_MODE_FREEFORM }
.toBundle(),
)
+ val deskId = taskRepository.getDeskIdForTask(taskId) ?: getDefaultDeskId(DEFAULT_DISPLAY)
startLaunchTransition(
TRANSIT_OPEN,
wct,
taskId,
+ deskId = deskId,
+ displayId = DEFAULT_DISPLAY,
remoteTransition = remoteTransition,
unminimizeReason = unminimizeReason,
)
@@ -980,19 +986,26 @@ class DesktopTasksController(
remoteTransition: RemoteTransition? = null,
unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
) {
- logV("moveTaskToFront taskId=%s", taskInfo.taskId)
+ val deskId =
+ taskRepository.getDeskIdForTask(taskInfo.taskId) ?: getDefaultDeskId(taskInfo.displayId)
+ logV("moveTaskToFront taskId=%s deskId=%s", taskInfo.taskId, deskId)
// If a task is tiled, another task should be brought to foreground with it so let
// tiling controller handle the request.
if (snapEventHandler.moveTaskToFrontIfTiled(taskInfo)) {
return
}
val wct = WindowContainerTransaction()
- wct.reorder(taskInfo.token, /* onTop= */ true, /* includingParents= */ true)
+ if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+ desksOrganizer.reorderTaskToFront(wct, deskId, taskInfo)
+ } else {
+ wct.reorder(taskInfo.token, /* onTop= */ true, /* includingParents= */ true)
+ }
startLaunchTransition(
transitionType = TRANSIT_TO_FRONT,
wct = wct,
launchingTaskId = taskInfo.taskId,
remoteTransition = remoteTransition,
+ deskId = deskId,
displayId = taskInfo.displayId,
unminimizeReason = unminimizeReason,
)
@@ -1004,14 +1017,22 @@ class DesktopTasksController(
wct: WindowContainerTransaction,
launchingTaskId: Int?,
remoteTransition: RemoteTransition? = null,
- displayId: Int = DEFAULT_DISPLAY,
+ deskId: Int,
+ displayId: Int,
unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
): IBinder {
+ logV(
+ "startLaunchTransition type=%s launchingTaskId=%d deskId=%d displayId=%d",
+ WindowManager.transitTypeToString(transitionType),
+ launchingTaskId,
+ deskId,
+ displayId,
+ )
// TODO: b/397619806 - Consolidate sharable logic with [handleFreeformTaskLaunch].
var launchTransaction = wct
val taskIdToMinimize =
addAndGetMinimizeChanges(
- displayId,
+ deskId,
launchTransaction,
newTaskId = launchingTaskId,
launchingNewIntent = launchingTaskId == null,
@@ -1025,21 +1046,20 @@ class DesktopTasksController(
)
var activationRunOnTransitStart: RunOnTransitStart? = null
val shouldActivateDesk =
- (DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue ||
- DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) &&
- !isDesktopModeShowing(displayId)
+ when {
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ->
+ !taskRepository.isDeskActive(deskId)
+ DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue -> {
+ !isDesktopModeShowing(displayId)
+ }
+ else -> false
+ }
if (shouldActivateDesk) {
- val deskIdToActivate =
- checkNotNull(
- launchingTaskId?.let { taskRepository.getDeskIdForTask(it) }
- ?: getDefaultDeskId(displayId)
- )
val activateDeskWct = WindowContainerTransaction()
// TODO: b/391485148 - pass in the launching task here to apply task-limit policy,
// but make sure to not do it twice since it is also done at the start of this
// function.
- activationRunOnTransitStart =
- addDeskActivationChanges(deskIdToActivate, activateDeskWct)
+ activationRunOnTransitStart = addDeskActivationChanges(deskId, activateDeskWct)
// Desk activation must be handled before app launch-related transactions.
activateDeskWct.merge(launchTransaction, /* transfer= */ true)
launchTransaction = activateDeskWct
@@ -1150,7 +1170,14 @@ class DesktopTasksController(
}
wct.sendPendingIntent(pendingIntent, intent, ops.toBundle())
- startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
+ val deskId = getDefaultDeskId(displayId)
+ startLaunchTransition(
+ TRANSIT_OPEN,
+ wct,
+ launchingTaskId = null,
+ deskId = deskId,
+ displayId = displayId,
+ )
}
/**
@@ -1201,7 +1228,8 @@ class DesktopTasksController(
} else {
null
}
- val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
+ val transition =
+ transitions.startTransition(TRANSIT_CHANGE, wct, moveToDisplayTransitionHandler)
deactivationRunnable?.invoke(transition)
return
}
@@ -1260,7 +1288,8 @@ class DesktopTasksController(
} else {
null
}
- val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
+ val transition =
+ transitions.startTransition(TRANSIT_CHANGE, wct, moveToDisplayTransitionHandler)
deactivationRunnable?.invoke(transition)
activationRunnable?.invoke(transition)
}
@@ -1625,7 +1654,10 @@ class DesktopTasksController(
}
}
- @Deprecated("Use activeDesk() instead.", ReplaceWith("activateDesk()"))
+ @Deprecated(
+ "Use addDeskActivationChanges() instead.",
+ ReplaceWith("addDeskActivationChanges()"),
+ )
private fun bringDesktopAppsToFront(
displayId: Int,
wct: WindowContainerTransaction,
@@ -2134,10 +2166,14 @@ class DesktopTasksController(
WINDOWING_MODE_FREEFORM -> {
val wct = WindowContainerTransaction()
wct.sendPendingIntent(launchIntent, fillIn, options.toBundle())
+ val deskId =
+ taskRepository.getDeskIdForTask(callingTaskInfo.taskId)
+ ?: getDefaultDeskId(callingTaskInfo.displayId)
startLaunchTransition(
transitionType = TRANSIT_OPEN,
wct = wct,
launchingTaskId = null,
+ deskId = deskId,
displayId = callingTaskInfo.displayId,
)
}
@@ -2217,6 +2253,7 @@ class DesktopTasksController(
logV("skip keyguard is locked")
return null
}
+ val deskId = getDefaultDeskId(task.displayId)
val wct = WindowContainerTransaction()
if (shouldFreeformTaskLaunchSwitchToFullscreen(task)) {
logD("Bring desktop tasks to front on transition=taskId=%d", task.taskId)
@@ -2239,7 +2276,8 @@ class DesktopTasksController(
runOnTransitStart?.invoke(transition)
return wct
}
- bringDesktopAppsToFront(task.displayId, wct, task.taskId)
+ val runOnTransitStart = addDeskActivationChanges(deskId, wct, task)
+ runOnTransitStart?.invoke(transition)
wct.reorder(task.token, true)
return wct
}
@@ -2279,7 +2317,7 @@ class DesktopTasksController(
reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
// 2) minimize a Task if needed.
- val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
+ val taskIdToMinimize = addAndGetMinimizeChanges(deskId, wct, task.taskId)
addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
if (taskIdToMinimize != null) {
addPendingMinimizeTransition(transition, taskIdToMinimize, MinimizeReason.TASK_LIMIT)
@@ -2302,25 +2340,42 @@ class DesktopTasksController(
return WindowContainerTransaction().also { wct ->
val deskId = getDefaultDeskId(task.displayId)
addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId)
- // In some launches home task is moved behind new task being launched. Make sure
- // that's not the case for launches in desktop. Also, if this launch is the first
- // one to trigger the desktop mode (e.g., when [forceEnterDesktop()]), activate the
- // desktop mode here.
- if (
- task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0 ||
- !isDesktopModeShowing(task.displayId)
- ) {
- bringDesktopAppsToFront(task.displayId, wct, task.taskId)
- wct.reorder(task.token, true)
- }
-
- // Desktop Mode is already showing and we're launching a new Task - we might need to
- // minimize another Task.
- val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
- taskIdToMinimize?.let {
- addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT)
- }
- addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
+ val runOnTransitStart: RunOnTransitStart? =
+ if (
+ task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0 ||
+ !isDesktopModeShowing(task.displayId)
+ ) {
+ // In some launches home task is moved behind new task being launched. Make
+ // sure that's not the case for launches in desktop. Also, if this launch is
+ // the first one to trigger the desktop mode (e.g., when
+ // [forceEnterDesktop()]), activate the desk here.
+ val activationRunnable =
+ addDeskActivationChanges(
+ deskId = deskId,
+ wct = wct,
+ newTask = task,
+ addPendingLaunchTransition = true,
+ )
+ wct.reorder(task.token, true)
+ activationRunnable
+ } else {
+ { transition: IBinder ->
+ // The desk was already showing and we're launching a new Task - we
+ // might need to minimize another Task.
+ val taskIdToMinimize =
+ addAndGetMinimizeChanges(deskId, wct, task.taskId)
+ taskIdToMinimize?.let { minimizingTaskId ->
+ addPendingMinimizeTransition(
+ transition,
+ minimizingTaskId,
+ MinimizeReason.TASK_LIMIT,
+ )
+ }
+ // Also track the pending launching task.
+ addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
+ }
+ }
+ runOnTransitStart?.invoke(transition)
desktopImmersiveController.exitImmersiveIfApplicable(
transition,
wct,
@@ -2644,7 +2699,7 @@ class DesktopTasksController(
/** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
private fun addAndGetMinimizeChanges(
- displayId: Int,
+ deskId: Int,
wct: WindowContainerTransaction,
newTaskId: Int?,
launchingNewIntent: Boolean = false,
@@ -2653,7 +2708,7 @@ class DesktopTasksController(
require(newTaskId == null || !launchingNewIntent)
return desktopTasksLimiter
.get()
- .addAndGetMinimizeTaskChanges(displayId, wct, newTaskId, launchingNewIntent)
+ .addAndGetMinimizeTaskChanges(deskId, wct, newTaskId, launchingNewIntent)
}
private fun addPendingMinimizeTransition(
@@ -2715,11 +2770,20 @@ class DesktopTasksController(
activateDesk(deskId, remoteTransition)
}
- /** Activates the given desk but without starting a transition. */
+ /**
+ * Applies the necessary [wct] changes to activate the given desk.
+ *
+ * When a task is being brought into a desk together with the activation, then [newTask] is not
+ * null and may be used to run other desktop policies, such as minimizing another task if the
+ * task limit has been exceeded.
+ */
fun addDeskActivationChanges(
deskId: Int,
wct: WindowContainerTransaction,
- newTask: RunningTaskInfo? = null,
+ newTask: TaskInfo? = null,
+ // TODO: b/362720497 - should this be true in other places? Can it be calculated locally
+ // without having to specify the value?
+ addPendingLaunchTransition: Boolean = false,
): RunOnTransitStart? {
logV("addDeskActivationChanges newTaskId=%d deskId=%d", newTask?.taskId, deskId)
val newTaskIdInFront = newTask?.taskId
@@ -2734,6 +2798,9 @@ class DesktopTasksController(
minimizeReason = MinimizeReason.TASK_LIMIT,
)
}
+ if (newTask != null && addPendingLaunchTransition) {
+ addPendingAppLaunchTransition(transition, newTask.taskId, taskIdToMinimize)
+ }
}
}
prepareForDeskActivation(displayId, wct)
@@ -2744,9 +2811,20 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
doesAnyTaskRequireTaskbarRounding(displayId)
)
- // TODO: b/362720497 - activating a desk with the intention to move a new task to
- // it means we may need to minimize something in the activating desk. Do so here
- // similar to how it's done in #bringDesktopAppsToFront.
+ val expandedTasksOrderedFrontToBack =
+ taskRepository.getExpandedTasksIdsInDeskOrdered(deskId = deskId)
+ // If we're adding a new Task we might need to minimize an old one
+ val taskIdToMinimize =
+ desktopTasksLimiter
+ .getOrNull()
+ ?.getTaskIdToMinimize(expandedTasksOrderedFrontToBack, newTaskIdInFront)
+ if (taskIdToMinimize != null) {
+ val taskToMinimize = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize)
+ // TODO(b/365725441): Handle non running task minimization
+ if (taskToMinimize != null) {
+ desksOrganizer.minimizeTask(wct, deskId, taskToMinimize)
+ }
+ }
return { transition ->
val activateDeskTransition =
if (newTaskIdInFront != null) {
@@ -2764,6 +2842,9 @@ class DesktopTasksController(
)
}
desksTransitionObserver.addPendingTransition(activateDeskTransition)
+ taskIdToMinimize?.let { minimizingTask ->
+ addPendingMinimizeTransition(transition, minimizingTask, MinimizeReason.TASK_LIMIT)
+ }
}
}
@@ -3343,7 +3424,14 @@ class DesktopTasksController(
if (windowingMode == WINDOWING_MODE_FREEFORM) {
if (DesktopModeFlags.ENABLE_DESKTOP_TAB_TEARING_MINIMIZE_ANIMATION_BUGFIX.isTrue()) {
// TODO b/376389593: Use a custom tab tearing transition/animation
- startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
+ val deskId = getDefaultDeskId(DEFAULT_DISPLAY)
+ startLaunchTransition(
+ TRANSIT_OPEN,
+ wct,
+ launchingTaskId = null,
+ deskId = deskId,
+ displayId = DEFAULT_DISPLAY,
+ )
} else {
desktopModeDragAndDropTransitionHandler.handleDropEvent(wct)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
index b9b4d9e4bbd8..4ca58823b52b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
@@ -22,6 +22,7 @@ import android.os.Handler
import android.os.IBinder
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_BACK
+import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
@@ -31,6 +32,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
+import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.sysui.UserChangeListener
@@ -38,17 +40,18 @@ import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TransitionObserver
/**
- * Limits the number of tasks shown in Desktop Mode.
+ * Keeps track of minimized tasks and limits the number of tasks shown in Desktop Mode.
*
- * This class should only be used if
- * [android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT] is enabled and
- * [maxTasksLimit] is strictly greater than 0.
+ * [maxTasksLimit] must be strictly greater than 0 if it's given.
+ *
+ * TODO(b/400634379): Separate two responsibilities of this class into two classes.
*/
class DesktopTasksLimiter(
transitions: Transitions,
private val desktopUserRepositories: DesktopUserRepositories,
private val shellTaskOrganizer: ShellTaskOrganizer,
- private val maxTasksLimit: Int,
+ private val desksOrganizer: DesksOrganizer,
+ private val maxTasksLimit: Int?,
private val interactionJankMonitor: InteractionJankMonitor,
private val context: Context,
@ShellMainThread private val handler: Handler,
@@ -59,13 +62,19 @@ class DesktopTasksLimiter(
private var userId: Int
init {
- require(maxTasksLimit > 0) {
- "DesktopTasksLimiter: maxTasksLimit should be greater than 0. Current value: $maxTasksLimit."
+ maxTasksLimit?.let {
+ require(it > 0) {
+ "DesktopTasksLimiter: maxTasksLimit should be greater than 0. Current value: $it."
+ }
}
transitions.registerObserver(minimizeTransitionObserver)
userId = ActivityManager.getCurrentUser()
desktopUserRepositories.current.addActiveTaskListener(leftoverMinimizedTasksRemover)
- logV("Starting limiter with a maximum of %d tasks", maxTasksLimit)
+ if (maxTasksLimit != null) {
+ logV("Starting limiter with a maximum of %d tasks", maxTasksLimit)
+ } else {
+ logV("Starting limiter without the task limit")
+ }
}
data class TaskDetails(
@@ -252,7 +261,7 @@ class DesktopTasksLimiter(
* returning the task to minimize.
*/
fun addAndGetMinimizeTaskChanges(
- displayId: Int,
+ deskId: Int,
wct: WindowContainerTransaction,
newFrontTaskId: Int?,
launchingNewIntent: Boolean = false,
@@ -261,15 +270,19 @@ class DesktopTasksLimiter(
val taskRepository = desktopUserRepositories.current
val taskIdToMinimize =
getTaskIdToMinimize(
- taskRepository.getExpandedTasksOrdered(displayId),
+ taskRepository.getExpandedTasksIdsInDeskOrdered(deskId),
newFrontTaskId,
launchingNewIntent,
)
- // If it's a running task, reorder it to back.
taskIdToMinimize
?.let { shellTaskOrganizer.getRunningTaskInfo(it) }
- // TODO: b/391485148 - this won't really work with multi-desks enabled.
- ?.let { wct.reorder(it.token, /* onTop= */ false) }
+ ?.let { task ->
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+ wct.reorder(task.token, /* onTop= */ false)
+ } else {
+ desksOrganizer.minimizeTask(wct, deskId, task)
+ }
+ }
return taskIdToMinimize
}
@@ -325,7 +338,7 @@ class DesktopTasksLimiter(
launchingNewIntent: Boolean,
): Int? {
val newTasksOpening = if (launchingNewIntent) 1 else 0
- if (visibleOrderedTasks.size + newTasksOpening <= maxTasksLimit) {
+ if (visibleOrderedTasks.size + newTasksOpening <= (maxTasksLimit ?: Int.MAX_VALUE)) {
logV("No need to minimize; tasks below limit")
// No need to minimize anything
return null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index 26a5d5b52358..7dabeb7c9d15 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -32,12 +32,10 @@ import android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVI
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
import com.android.internal.protolog.ProtoLog
-import com.android.window.flags.Flags
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.back.BackAnimationController
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.isExitDesktopModeTransition
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
-import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -59,7 +57,6 @@ class DesktopTasksTransitionObserver(
private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
private val backAnimationController: BackAnimationController,
private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
- private val desksTransitionObserver: DesksTransitionObserver,
shellInit: ShellInit,
) : Transitions.TransitionObserver {
@@ -89,7 +86,6 @@ class DesktopTasksTransitionObserver(
finishTransaction: SurfaceControl.Transaction,
) {
// TODO: b/332682201 Update repository state
- desksTransitionObserver.onTransitionReady(transition, info)
if (
DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC
.isTrue() && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
@@ -107,7 +103,7 @@ class DesktopTasksTransitionObserver(
info.changes.forEach { change ->
change.taskInfo?.let { taskInfo ->
if (
- Flags.enableDesktopWindowingPip() &&
+ DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue &&
desktopRepository.isTaskMinimizedPipInDisplay(
taskInfo.displayId,
taskInfo.taskId,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index d396d8bff2b8..4f511a901756 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -25,6 +25,7 @@ import android.os.SystemProperties
import android.os.UserHandle
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CLOSE
+import android.window.DesktopModeFlags
import android.window.TransitionInfo
import android.window.TransitionInfo.Change
import android.window.TransitionRequestInfo
@@ -118,6 +119,7 @@ sealed class DragToDesktopTransitionHandler(
fun startDragToDesktopTransition(
taskInfo: RunningTaskInfo,
dragToDesktopAnimator: MoveToDesktopAnimator,
+ visualIndicator: DesktopModeVisualIndicator?,
) {
if (inProgress) {
logV("Drag to desktop transition already in progress.")
@@ -163,12 +165,14 @@ sealed class DragToDesktopTransitionHandler(
dragAnimator = dragToDesktopAnimator,
startTransitionToken = startTransitionToken,
otherSplitTask = otherTask,
+ visualIndicator = visualIndicator,
)
} else {
TransitionState.FromFullscreen(
draggedTaskId = taskInfo.taskId,
dragAnimator = dragToDesktopAnimator,
startTransitionToken = startTransitionToken,
+ visualIndicator = visualIndicator,
)
}
}
@@ -277,6 +281,7 @@ sealed class DragToDesktopTransitionHandler(
val state = requireTransitionState()
val taskInfo = state.draggedTaskChange?.taskInfo ?: error("Expected non-null taskInfo")
val animatedTaskBounds = getAnimatedTaskBounds()
+ state.dragAnimator.cancelAnimator()
requestSplitSelect(wct, taskInfo, splitPosition, animatedTaskBounds)
}
@@ -288,7 +293,6 @@ sealed class DragToDesktopTransitionHandler(
val scaledWidth = taskBounds.width() * taskScale
val scaledHeight = taskBounds.height() * taskScale
val dragPosition = PointF(state.dragAnimator.position)
- state.dragAnimator.cancelAnimator()
return Rect(
dragPosition.x.toInt(),
dragPosition.y.toInt(),
@@ -321,22 +325,26 @@ sealed class DragToDesktopTransitionHandler(
// TODO(b/391928049): update density once we can drag from desktop to bubble
val state = requireTransitionState()
val taskInfo = state.draggedTaskChange?.taskInfo ?: error("Expected non-null taskInfo")
- val taskBounds = getAnimatedTaskBounds()
+ val dragPosition = PointF(state.dragAnimator.position)
+ val scale = state.dragAnimator.scale
+ val cornerRadius = state.dragAnimator.cornerRadius
state.dragAnimator.cancelAnimator()
- requestBubble(wct, taskInfo, onLeft, taskBounds)
+ requestBubble(wct, taskInfo, onLeft, scale, cornerRadius, dragPosition)
}
private fun requestBubble(
wct: WindowContainerTransaction,
taskInfo: RunningTaskInfo,
onLeft: Boolean,
- taskBounds: Rect = Rect(taskInfo.configuration.windowConfiguration.bounds),
+ taskScale: Float = 1f,
+ cornerRadius: Float = 0f,
+ dragPosition: PointF = PointF(0f, 0f),
) {
val controller =
bubbleController.orElseThrow { IllegalStateException("BubbleController not set") }
controller.expandStackAndSelectBubble(
taskInfo,
- BubbleTransitions.DragData(taskBounds, wct, onLeft),
+ BubbleTransitions.DragData(onLeft, taskScale, cornerRadius, dragPosition, wct),
)
}
@@ -457,6 +465,13 @@ sealed class DragToDesktopTransitionHandler(
state.surfaceLayers = layers
state.startTransitionFinishCb = finishCallback
state.startTransitionFinishTransaction = finishTransaction
+
+ val taskChange = state.draggedTaskChange ?: error("Expected non-null task change.")
+ val taskInfo = taskChange.taskInfo ?: error("Expected non-null task info.")
+
+ if (DesktopModeFlags.ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX.isTrue) {
+ attachIndicatorToTransitionRoot(state, info, taskInfo, startTransaction)
+ }
startTransaction.apply()
if (state.cancelState == CancelState.NO_CANCEL) {
@@ -485,8 +500,6 @@ sealed class DragToDesktopTransitionHandler(
} else {
SPLIT_POSITION_BOTTOM_OR_RIGHT
}
- val taskInfo =
- state.draggedTaskChange?.taskInfo ?: error("Expected non-null task info.")
val wct = WindowContainerTransaction()
restoreWindowOrder(wct)
state.startTransitionFinishTransaction?.apply()
@@ -511,6 +524,21 @@ sealed class DragToDesktopTransitionHandler(
return true
}
+ private fun attachIndicatorToTransitionRoot(
+ state: TransitionState,
+ info: TransitionInfo,
+ taskInfo: RunningTaskInfo,
+ t: SurfaceControl.Transaction,
+ ) {
+ val transitionRoot = info.getRoot(info.findRootIndex(taskInfo.displayId))
+ state.visualIndicator?.let {
+ // Attach the indicator to the transition root so that it's removed at the end of the
+ // transition regardless of whether we managed to release the indicator.
+ it.reparentLeash(t, transitionRoot.leash)
+ it.fadeInIndicator()
+ }
+ }
+
/**
* Calculates start drag to desktop layers for transition [info]. The leash layer is calculated
* based on its change position in the transition, e.g. `appLayer = appLayers - i`, where i is
@@ -901,6 +929,7 @@ sealed class DragToDesktopTransitionHandler(
abstract var surfaceLayers: DragToDesktopLayers?
abstract var cancelState: CancelState
abstract var startAborted: Boolean
+ abstract val visualIndicator: DesktopModeVisualIndicator?
data class FromFullscreen(
override val draggedTaskId: Int,
@@ -915,6 +944,7 @@ sealed class DragToDesktopTransitionHandler(
override var surfaceLayers: DragToDesktopLayers? = null,
override var cancelState: CancelState = CancelState.NO_CANCEL,
override var startAborted: Boolean = false,
+ override val visualIndicator: DesktopModeVisualIndicator?,
var otherRootChanges: MutableList<Change> = mutableListOf(),
) : TransitionState()
@@ -931,6 +961,7 @@ sealed class DragToDesktopTransitionHandler(
override var surfaceLayers: DragToDesktopLayers? = null,
override var cancelState: CancelState = CancelState.NO_CANCEL,
override var startAborted: Boolean = false,
+ override val visualIndicator: DesktopModeVisualIndicator?,
var splitRootChange: Change? = null,
var otherSplitTask: Int,
) : TransitionState()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
index 919e8164b58e..23562388b3e5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
@@ -130,6 +130,12 @@ constructor(
}
}
+ /** Reparent the indicator to {@code newParent}. */
+ fun reparentLeash(t: SurfaceControl.Transaction, newParent: SurfaceControl) {
+ val leash = indicatorLeash ?: return
+ t.reparent(leash, newParent)
+ }
+
private fun showIndicator(taskSurface: SurfaceControl, leash: SurfaceControl) {
mainExecutor.execute {
indicatorLeash = leash
@@ -166,7 +172,7 @@ constructor(
displayController.getDisplayLayout(taskInfo.displayId)
?: error("Expected to find DisplayLayout for taskId${taskInfo.taskId}.")
if (currentType == IndicatorType.NO_INDICATOR) {
- fadeInIndicator(layout, newType, taskInfo.displayId, snapEventHandler)
+ fadeInIndicatorInternal(layout, newType, taskInfo.displayId, snapEventHandler)
} else if (newType == IndicatorType.NO_INDICATOR) {
fadeOutIndicator(
layout,
@@ -195,10 +201,22 @@ constructor(
}
/**
+ * Fade indicator in as provided type.
+ *
+ * Animator fades the indicator in while expanding the bounds outwards.
+ */
+ fun fadeInIndicator(layout: DisplayLayout, type: IndicatorType, displayId: Int) {
+ if (isReleased) return
+ desktopExecutor.execute {
+ fadeInIndicatorInternal(layout, type, displayId, snapEventHandler)
+ }
+ }
+
+ /**
* Fade indicator in as provided type. Animator fades it in while expanding the bounds outwards.
*/
@VisibleForTesting
- fun fadeInIndicator(
+ fun fadeInIndicatorInternal(
layout: DisplayLayout,
type: IndicatorType,
displayId: Int,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
index fc359d7d67b6..8c4bc2598dff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
@@ -40,6 +40,13 @@ interface DesksOrganizer {
task: ActivityManager.RunningTaskInfo,
)
+ /** Reorders a desk's task to the front. */
+ fun reorderTaskToFront(
+ wct: WindowContainerTransaction,
+ deskId: Int,
+ task: ActivityManager.RunningTaskInfo,
+ )
+
/** Minimizes the given task of the given deskId. */
fun minimizeTask(
wct: WindowContainerTransaction,
@@ -47,6 +54,13 @@ interface DesksOrganizer {
task: ActivityManager.RunningTaskInfo,
)
+ /** Unminimize the given task of the given desk. */
+ fun unminimizeTask(
+ wct: WindowContainerTransaction,
+ deskId: Int,
+ task: ActivityManager.RunningTaskInfo,
+ )
+
/** Whether the change is for the given desk id. */
fun isDeskChange(change: TransitionInfo.Change, deskId: Int): Boolean
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
index f576258ebdaa..2130474ff603 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
@@ -110,7 +110,31 @@ class RootTaskDesksOrganizer(
wct.reparent(task.token, root.taskInfo.token, /* onTop= */ true)
}
+ override fun reorderTaskToFront(
+ wct: WindowContainerTransaction,
+ deskId: Int,
+ task: RunningTaskInfo,
+ ) {
+ logV("reorderTaskToFront task=${task.taskId} desk=$deskId")
+ val root = deskRootsByDeskId[deskId] ?: error("Root not found for desk: $deskId")
+ if (task.taskId in root.children) {
+ wct.reorder(task.token, /* onTop= */ true, /* includingParents= */ true)
+ return
+ }
+ val minimizationRoot =
+ checkNotNull(deskMinimizationRootsByDeskId[deskId]) {
+ "Minimization root not found for desk: $deskId"
+ }
+ if (task.taskId in minimizationRoot.children) {
+ unminimizeTask(wct, deskId, task)
+ wct.reorder(task.token, /* onTop= */ true, /* includingParents= */ true)
+ return
+ }
+ logE("Attempted to reorder task=${task.taskId} in desk=$deskId but it was not a child")
+ }
+
override fun minimizeTask(wct: WindowContainerTransaction, deskId: Int, task: RunningTaskInfo) {
+ logV("minimizeTask task=${task.taskId} desk=$deskId")
val deskRoot =
checkNotNull(deskRootsByDeskId[deskId]) { "Root not found for desk: $deskId" }
val minimizationRoot =
@@ -129,6 +153,30 @@ class RootTaskDesksOrganizer(
wct.reparent(task.token, minimizationRoot.token, /* onTop= */ true)
}
+ override fun unminimizeTask(
+ wct: WindowContainerTransaction,
+ deskId: Int,
+ task: RunningTaskInfo,
+ ) {
+ val taskId = task.taskId
+ logV("unminimizeTask task=$taskId desk=$deskId")
+ val deskRoot =
+ checkNotNull(deskRootsByDeskId[deskId]) { "Root not found for desk: $deskId" }
+ val minimizationRoot =
+ checkNotNull(deskMinimizationRootsByDeskId[deskId]) {
+ "Minimization root not found for desk: $deskId"
+ }
+ if (taskId in deskRoot.children) {
+ logV("Task #$taskId is already unminimized in desk=$deskId")
+ return
+ }
+ if (taskId !in minimizationRoot.children) {
+ logE("Attempted to unminimize task=$taskId in desk=$deskId but it was not a child")
+ return
+ }
+ wct.reparent(task.token, deskRoot.token, /* onTop= */ true)
+ }
+
override fun isDeskChange(change: TransitionInfo.Change, deskId: Int): Boolean =
(isDeskRootChange(change) && change.taskId == deskId) ||
(getDeskMinimizationRootInChange(change)?.deskId == deskId)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index 8059b94685ba..f89ba0a168d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.wm.shell.desktopmode.DesktopImmersiveController;
+import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
@@ -52,6 +53,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
private final WindowDecorViewModel mWindowDecorViewModel;
private final Optional<TaskChangeListener> mTaskChangeListener;
private final FocusTransitionObserver mFocusTransitionObserver;
+ private final Optional<DesksTransitionObserver> mDesksTransitionObserver;
private final Map<IBinder, List<ActivityManager.RunningTaskInfo>> mTransitionToTaskInfo =
new HashMap<>();
@@ -63,12 +65,14 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
Optional<DesktopImmersiveController> desktopImmersiveController,
WindowDecorViewModel windowDecorViewModel,
Optional<TaskChangeListener> taskChangeListener,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ Optional<DesksTransitionObserver> desksTransitionObserver) {
mTransitions = transitions;
mDesktopImmersiveController = desktopImmersiveController;
mWindowDecorViewModel = windowDecorViewModel;
mTaskChangeListener = taskChangeListener;
mFocusTransitionObserver = focusTransitionObserver;
+ mDesksTransitionObserver = desksTransitionObserver;
if (FreeformComponents.requiresFreeformComponents(context)) {
shellInit.addInitCallback(this::onInit, this);
}
@@ -85,6 +89,10 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startT,
@NonNull SurfaceControl.Transaction finishT) {
+ // Update desk state first, otherwise [TaskChangeListener] may update desktop task state
+ // under an outdated active desk if a desk switch and a task update happen in the same
+ // transition, such as when unminimizing a task from an inactive desk.
+ mDesksTransitionObserver.ifPresent(o -> o.onTransitionReady(transition, info));
if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
// TODO(b/367268953): Remove when DesktopTaskListener is introduced and the repository
// is updated from there **before** the |mWindowDecorViewModel| methods are invoked.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 04f03361258e..0966110d2f41 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -70,6 +70,7 @@ import android.view.Choreographer;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
+import android.window.DesktopModeFlags;
import android.window.DisplayAreaInfo;
import android.window.TaskOrganizer;
import android.window.TaskSnapshot;
@@ -78,7 +79,6 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -781,7 +781,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// TODO(b/377581840): Update this check to include non-minimized cases, e.g. split to PiP etc.
private boolean isPipExitingToDesktopMode() {
DesktopRepository currentRepo = getCurrentRepo();
- return Flags.enableDesktopWindowingPip() && currentRepo != null
+ return DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue() && currentRepo != null
&& (currentRepo.isAnyDeskActive(mTaskInfo.displayId)
|| isDisplayInFreeform());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 242f7fa5f1b1..5706f19f177a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -39,11 +39,11 @@ import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
+import android.window.DesktopModeFlags;
import androidx.annotation.VisibleForTesting;
import com.android.internal.policy.TaskResizingAlgorithm;
-import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
@@ -183,7 +183,7 @@ public class PipResizeGestureHandler {
private void reloadResources() {
final Resources res = mContext.getResources();
mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size);
- mEnableDragCornerResize = Flags.enableDesktopWindowingPip();
+ mEnableDragCornerResize = DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue();
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
index 65099c2dfb9d..671eae3d84ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
@@ -153,7 +153,12 @@ public class PhonePipMenuController implements PipMenuController,
mPipUiEventLogger = pipUiEventLogger;
mPipTransitionState.addPipTransitionStateChangedListener(this);
-
+ // Clear actions after exit PiP. Otherwise, next PiP could accidentally inherit the
+ // actions provided by the previous app in PiP mode.
+ mPipBoundsState.addOnPipComponentChangedListener(((oldPipComponent, newPipComponent) -> {
+ if (mAppActions != null) mAppActions.clear();
+ mCloseAction = null;
+ }));
mPipTaskListener.addParamsChangedListener(new PipTaskListener.PipParamsChangedCallback() {
@Override
public void onActionsChanged(List<RemoteAction> actions, RemoteAction closeAction) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
index d6634845ee21..294ef48c01d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
@@ -61,7 +61,7 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener,
private final PipBoundsState mPipBoundsState;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final ShellExecutor mMainExecutor;
- private final PictureInPictureParams mPictureInPictureParams =
+ private PictureInPictureParams mPictureInPictureParams =
new PictureInPictureParams.Builder().build();
private boolean mWaitingForAspectRatioChange = false;
@@ -92,6 +92,11 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener,
}
mPipResizeAnimatorSupplier = PipResizeAnimator::new;
mPipScheduler.setPipParamsSupplier(this::getPictureInPictureParams);
+ // Reset {@link #mPictureInPictureParams} after exiting PiP. For instance, next Activity
+ // with null aspect ratio would accidentally inherit the aspect ratio from a previous
+ // PiP Activity.
+ mPipBoundsState.addOnPipComponentChangedListener(((oldPipComponent, newPipComponent) ->
+ mPictureInPictureParams = new PictureInPictureParams.Builder().build()));
}
void setPictureInPictureParams(@Nullable PictureInPictureParams params) {
@@ -138,9 +143,8 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener,
if (mPictureInPictureParams.hasSetAspectRatio()
&& mPipBoundsAlgorithm.isValidPictureInPictureAspectRatio(newAspectRatio)
&& PipUtils.aspectRatioChanged(newAspectRatio, mPipBoundsState.getAspectRatio())) {
- mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
- onAspectRatioChanged(newAspectRatio);
- });
+ mPipTransitionState.setOnIdlePipTransitionStateRunnable(
+ () -> onAspectRatioChanged(newAspectRatio));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index fed336b17f19..65fa9b4b5529 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -52,6 +52,7 @@ import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.TransitionUtil;
+import com.android.wm.shell.shared.split.SplitScreenConstants;
import com.android.wm.shell.transition.OneShotRemoteHandler;
import com.android.wm.shell.transition.Transitions;
@@ -362,7 +363,8 @@ class SplitScreenTransitions {
WindowContainerTransaction wct,
@Nullable RemoteTransition remoteTransition,
Transitions.TransitionHandler handler,
- int extraTransitType, boolean resizeAnim) {
+ int extraTransitType, boolean resizeAnim,
+ @SplitScreenConstants.PersistentSnapPosition int snapPosition) {
if (mPendingEnter != null) {
ProtoLog.v(WM_SHELL_TRANSITIONS, " splitTransition "
+ " skip to start enter split transition since it already exist. ");
@@ -373,16 +375,18 @@ class SplitScreenTransitions {
.onSplitAnimationInvoked(true /*animationRunning*/));
}
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
- setEnterTransition(transition, remoteTransition, extraTransitType, resizeAnim);
+ setEnterTransition(transition, remoteTransition, extraTransitType, resizeAnim,
+ snapPosition);
return transition;
}
/** Sets a transition to enter split. */
void setEnterTransition(@NonNull IBinder transition,
@Nullable RemoteTransition remoteTransition,
- int extraTransitType, boolean resizeAnim) {
+ int extraTransitType, boolean resizeAnim,
+ int snapPosition) {
mPendingEnter = new EnterSession(
- transition, remoteTransition, extraTransitType, resizeAnim);
+ transition, remoteTransition, extraTransitType, resizeAnim, snapPosition);
ProtoLog.v(WM_SHELL_TRANSITIONS, " splitTransition "
+ " deduced Enter split screen");
@@ -675,13 +679,16 @@ class SplitScreenTransitions {
/** Bundled information of enter transition. */
class EnterSession extends TransitSession {
final boolean mResizeAnim;
+ /** The starting snap position we'll enter into with this transition. */
+ final @SplitScreenConstants.PersistentSnapPosition int mEnteringPosition;
EnterSession(IBinder transition,
@Nullable RemoteTransition remoteTransition,
- int extraTransitType, boolean resizeAnim) {
+ int extraTransitType, boolean resizeAnim, int snapPosition) {
super(transition, null /* consumedCallback */, null /* finishedCallback */,
remoteTransition, extraTransitType);
this.mResizeAnim = resizeAnim;
+ this.mEnteringPosition = snapPosition;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index e1b57e229d36..c370c0cb0930 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -653,7 +653,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null, this,
isSplitScreenVisible()
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
- !mIsDropEntering);
+ !mIsDropEntering, SNAP_TO_2_50_50);
// Due to drag already pip task entering split by this method so need to reset flag here.
mIsDropEntering = false;
@@ -787,7 +787,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering, index);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
- extraTransitType, !mIsDropEntering);
+ extraTransitType, !mIsDropEntering, SNAP_TO_2_50_50);
}
/**
@@ -833,7 +833,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering, index);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
- extraTransitType, !mIsDropEntering);
+ extraTransitType, !mIsDropEntering, SNAP_TO_2_50_50);
}
/**
@@ -1050,7 +1050,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mPausingTasks.clear();
}
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, remoteTransition, this,
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, snapPosition);
setEnterInstanceId(instanceId);
}
@@ -1140,7 +1140,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, remoteTransition, this,
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, snapPosition);
setEnterInstanceId(instanceId);
}
@@ -1645,6 +1645,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
grantFocusToStage(stageToFocus);
}
+ private void grantFocusForSnapPosition(@PersistentSnapPosition int enteringPosition) {
+ switch (enteringPosition) {
+ case SNAP_TO_2_90_10 -> grantFocusToPosition(true /*leftOrTop*/);
+ case SNAP_TO_2_10_90 -> grantFocusToPosition(false /*leftOrTop*/);
+ default -> { /*no-op*/ }
+ }
+ }
+
private void clearRequestIfPresented() {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "clearRequestIfPresented");
if (mSideStage.mVisible && mSideStage.mHasChildren
@@ -2911,8 +2919,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// split, prepare to enter split screen.
prepareEnterSplitScreen(out);
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
- } else if (isSplitScreenVisible() && isOpening) {
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering, SNAP_TO_2_50_50);
+ } else if (enableFlexibleTwoAppSplit() && isSplitScreenVisible() && isOpening) {
// launching into an existing split stage; possibly launchAdjacent
// If we're replacing a pip-able app, we need to let mixed handler take care of
// it. Otherwise we'll just treat it as an enter+resize
@@ -2920,7 +2928,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// updated layout will get applied in startAnimation pendingResize
mSplitTransitions.setEnterTransition(transition,
request.getRemoteTransition(),
- TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, true /*resizeAnim*/);
+ TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, true /*resizeAnim*/,
+ SNAP_TO_2_50_50);
}
} else if (inFullscreen && isSplitScreenVisible()) {
// If the trigger task is in fullscreen and in split, exit split and place
@@ -2998,14 +3007,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
out = new WindowContainerTransaction();
prepareEnterSplitScreen(out);
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering, SNAP_TO_2_50_50);
return out;
}
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "handleRequest: transition=%d "
+ "restoring to split", request.getDebugId());
out = new WindowContainerTransaction();
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
- TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, false /* resizeAnim */);
+ TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, false /* resizeAnim */,
+ SNAP_TO_2_50_50);
}
return out;
}
@@ -3192,7 +3202,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (keepSplitWithPip) {
// Set an enter transition for when startAnimation gets called again
mSplitTransitions.setEnterTransition(transition, /*remoteTransition*/ null,
- TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, /*resizeAnim*/ false);
+ TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, /*resizeAnim*/ false,
+ SNAP_TO_2_50_50);
} else {
int finalClosingTaskId = closingSplitTaskId;
mRecentTasks.ifPresent(recentTasks ->
@@ -3577,6 +3588,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
});
mPausingTasks.clear();
+ if (enableFlexibleTwoAppSplit()) {
+ grantFocusForSnapPosition(enterTransition.mEnteringPosition);
+ }
});
if (info.getType() == TRANSIT_CHANGE && !isSplitActive()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
index d36fc1247dad..a9df4bd1860d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
@@ -28,6 +28,7 @@ import static android.view.MotionEvent.ACTION_UP;
import android.annotation.NonNull;
import android.graphics.PointF;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -43,6 +44,8 @@ import androidx.annotation.Nullable;
* All touch events must be passed through this class to track a drag event.
*/
public class DragDetector {
+ private static final String TAG = "DragDetector";
+
private final MotionEventHandler mEventHandler;
private final PointF mInputDownPoint = new PointF();
@@ -109,8 +112,12 @@ public class DragDetector {
return mResultOfDownAction;
}
final int dragPointerIndex = ev.findPointerIndex(mDragPointerId);
+ // TODO(b/400635953): Separate the app header and its buttons'
+ // touch listeners so they're not handled by the same DragDetector.
if (dragPointerIndex == -1) {
- throw new IllegalStateException("Failed to find primary pointer!");
+ Log.w(TAG, "Invalid pointer index on ACTION_MOVE. Drag"
+ + " pointer id: " + mDragPointerId);
+ return mResultOfDownAction;
}
if (!mIsDragEvent) {
float dx = ev.getRawX(dragPointerIndex) - mInputDownPoint.x;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index ad2e23cb4028..ce786177290f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -471,32 +471,20 @@ class HandleMenu(
val rootView = LayoutInflater.from(context)
.inflate(R.layout.desktop_mode_window_decor_handle_menu, null /* root */) as View
- private val windowingButtonRippleRadius = context.resources
- .getDimensionPixelSize(R.dimen.desktop_mode_handle_menu_windowing_action_ripple_radius)
- private val windowingButtonDrawableInsets = DrawableInsets(
- vertical = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_base),
- horizontal = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_base)
- )
- private val windowingButtonDrawableInsetsLeft = DrawableInsets(
- vertical = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_base),
- horizontalLeft = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_shift),
- )
- private val windowingButtonDrawableInsetsRight = DrawableInsets(
- vertical = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_base),
- horizontalRight = context.resources
- .getDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_windowing_action_ripple_inset_shift)
- )
+ // Insets for ripple effect of App Info Pill. and Windowing Pill. buttons
+ val iconButtondrawableShiftInset = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_shift)
+ val iconButtondrawableBaseInset = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_base)
+ private val iconButtonRippleRadius = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius)
+ private val iconButtonDrawableInsetsBase = DrawableInsets(t=iconButtondrawableBaseInset,
+ b=iconButtondrawableBaseInset, l=iconButtondrawableBaseInset,
+ r=iconButtondrawableBaseInset)
+ private val iconButtonDrawableInsetsLeft = DrawableInsets(t=iconButtondrawableBaseInset,
+ b=iconButtondrawableBaseInset, l=iconButtondrawableShiftInset, r=0)
+ private val iconButtonDrawableInsetsRight = DrawableInsets(t=iconButtondrawableBaseInset,
+ b=iconButtondrawableBaseInset, l=0, r=iconButtondrawableShiftInset)
// App Info Pill.
private val appInfoPill = rootView.requireViewById<View>(R.id.app_info_pill)
@@ -713,6 +701,12 @@ class HandleMenu(
collapseMenuButton.apply {
imageTintList = ColorStateList.valueOf(style.textColor)
this.taskInfo = this@HandleMenuView.taskInfo
+
+ background = createRippleDrawable(
+ color = style.textColor,
+ cornerRadius = iconButtonRippleRadius,
+ drawableInsets = iconButtonDrawableInsetsBase
+ )
}
appNameView.setTextColor(style.textColor)
appNameView.startMarquee()
@@ -740,21 +734,15 @@ class HandleMenu(
desktopBtn.isEnabled = !taskInfo.isFreeform
desktopBtn.imageTintList = style.windowingButtonColor
- val startInsets = if (context.isRtl) {
- windowingButtonDrawableInsetsRight
- } else {
- windowingButtonDrawableInsetsLeft
- }
- val endInsets = if (context.isRtl) {
- windowingButtonDrawableInsetsLeft
- } else {
- windowingButtonDrawableInsetsRight
- }
+ val startInsets = if (context.isRtl) iconButtonDrawableInsetsRight
+ else iconButtonDrawableInsetsLeft
+ val endInsets = if (context.isRtl) iconButtonDrawableInsetsLeft
+ else iconButtonDrawableInsetsRight
fullscreenBtn.apply {
background = createRippleDrawable(
color = style.textColor,
- cornerRadius = windowingButtonRippleRadius,
+ cornerRadius = iconButtonRippleRadius,
drawableInsets = startInsets
)
}
@@ -762,23 +750,23 @@ class HandleMenu(
splitscreenBtn.apply {
background = createRippleDrawable(
color = style.textColor,
- cornerRadius = windowingButtonRippleRadius,
- drawableInsets = windowingButtonDrawableInsets
+ cornerRadius = iconButtonRippleRadius,
+ drawableInsets = iconButtonDrawableInsetsBase
)
}
floatingBtn.apply {
background = createRippleDrawable(
color = style.textColor,
- cornerRadius = windowingButtonRippleRadius,
- drawableInsets = windowingButtonDrawableInsets
+ cornerRadius = iconButtonRippleRadius,
+ drawableInsets = iconButtonDrawableInsetsBase
)
}
desktopBtn.apply {
background = createRippleDrawable(
color = style.textColor,
- cornerRadius = windowingButtonRippleRadius,
+ cornerRadius = iconButtonRippleRadius,
drawableInsets = endInsets
)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
index bdde096d4882..e8aac39a650c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
@@ -22,7 +22,7 @@ import android.annotation.DrawableRes
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
-import android.graphics.drawable.RippleDrawable
+import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
@@ -30,11 +30,11 @@ import android.view.ViewStub
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ProgressBar
+import android.window.DesktopModeFlags
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.content.ContextCompat
import com.android.wm.shell.R
-import android.window.DesktopModeFlags
private const val OPEN_MAXIMIZE_MENU_DELAY_ON_HOVER_MS = 350
private const val MAX_DRAWABLE_ALPHA = 255
@@ -109,14 +109,14 @@ class MaximizeButtonView(context: Context, attrs: AttributeSet) : FrameLayout(co
darkMode: Boolean,
iconForegroundColor: ColorStateList? = null,
baseForegroundColor: Int? = null,
- rippleDrawable: RippleDrawable? = null
+ backgroundDrawable: Drawable? = null
) {
if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue()) {
requireNotNull(iconForegroundColor) { "Icon foreground color must be non-null" }
requireNotNull(baseForegroundColor) { "Base foreground color must be non-null" }
- requireNotNull(rippleDrawable) { "Ripple drawable must be non-null" }
+ requireNotNull(backgroundDrawable) { "Background drawable must be non-null" }
maximizeWindow.imageTintList = iconForegroundColor
- maximizeWindow.background = rippleDrawable
+ maximizeWindow.background = backgroundDrawable
stubProgressBarContainer.setOnInflateListener { _, inflated ->
val progressBar = (inflated as FrameLayout)
.requireViewById(R.id.progress_bar) as ProgressBar
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
index 22bc9782170b..cf536eba8382 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
@@ -42,8 +42,6 @@ class MoveToDesktopAnimator @JvmOverloads constructor(
.setDuration(ANIMATION_DURATION.toLong())
.apply {
val t = SurfaceControl.Transaction()
- val cornerRadius = context.resources
- .getDimensionPixelSize(R.dimen.desktop_mode_dragged_task_radius).toFloat()
addUpdateListener {
setTaskPosition(mostRecentInput.x, mostRecentInput.y)
t.setScale(taskSurface, scale, scale)
@@ -57,6 +55,8 @@ class MoveToDesktopAnimator @JvmOverloads constructor(
val taskId get() = taskInfo.taskId
val position: PointF = PointF(0.0f, 0.0f)
+ val cornerRadius: Float = context.resources
+ .getDimensionPixelSize(R.dimen.desktop_mode_dragged_task_radius).toFloat()
/**
* Whether motion events from the drag gesture should affect the dragged surface or not. Used
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
index e18239d3eb70..f44b15a23b90 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
@@ -16,14 +16,13 @@
package com.android.wm.shell.windowdecor.common
import android.annotation.ColorInt
+import android.content.res.ColorStateList
import android.graphics.Color
+import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
-import com.android.wm.shell.windowdecor.common.OPACITY_11
-import com.android.wm.shell.windowdecor.common.OPACITY_15
-import android.content.res.ColorStateList
/**
* Represents drawable insets, specifying the number of pixels to inset a drawable from its bounds.
@@ -52,9 +51,9 @@ fun replaceColorAlpha(@ColorInt color: Int, alpha: Int): Int {
* Creates a RippleDrawable with specified color, corner radius, and insets.
*/
fun createRippleDrawable(
- @ColorInt color: Int,
- cornerRadius: Int,
- drawableInsets: DrawableInsets,
+ @ColorInt color: Int,
+ cornerRadius: Int,
+ drawableInsets: DrawableInsets,
): RippleDrawable {
return RippleDrawable(
ColorStateList(
@@ -86,3 +85,32 @@ fun createRippleDrawable(
}
)
}
+
+/**
+ * Creates a background drawable with specified color, corner radius, and insets.
+ */
+fun createBackgroundDrawable(
+ @ColorInt color: Int, cornerRadius: Int, drawableInsets: DrawableInsets
+): Drawable = LayerDrawable(arrayOf(
+ ShapeDrawable().apply {
+ shape = RoundRectShape(
+ FloatArray(8) { cornerRadius.toFloat() },
+ /* inset= */ null,
+ /* innerRadii= */ null
+ )
+ setTintList(ColorStateList(
+ arrayOf(
+ intArrayOf(android.R.attr.state_hovered),
+ intArrayOf(android.R.attr.state_pressed),
+ ),
+ intArrayOf(
+ replaceColorAlpha(color, OPACITY_11),
+ replaceColorAlpha(color, OPACITY_15),
+ )
+ ))
+ }
+)).apply {
+ require(numberOfLayers == 1) { "Must only contain one layer" }
+ setLayerInset(/* index= */ 0,
+ drawableInsets.l, drawableInsets.t, drawableInsets.r, drawableInsets.b)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index 8b054335d11c..30712b55bdfa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -23,10 +23,6 @@ import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
-import android.graphics.drawable.LayerDrawable
-import android.graphics.drawable.RippleDrawable
-import android.graphics.drawable.ShapeDrawable
-import android.graphics.drawable.shapes.RoundRectShape
import android.os.Bundle
import android.view.View
import android.view.View.OnLongClickListener
@@ -55,14 +51,12 @@ import com.android.internal.R.color.materialColorSurfaceDim
import com.android.wm.shell.R
import com.android.wm.shell.windowdecor.MaximizeButtonView
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
+import com.android.wm.shell.windowdecor.common.DrawableInsets
import com.android.wm.shell.windowdecor.common.OPACITY_100
-import com.android.wm.shell.windowdecor.common.OPACITY_11
-import com.android.wm.shell.windowdecor.common.OPACITY_15
import com.android.wm.shell.windowdecor.common.OPACITY_55
import com.android.wm.shell.windowdecor.common.OPACITY_65
import com.android.wm.shell.windowdecor.common.Theme
-import com.android.wm.shell.windowdecor.common.DrawableInsets
-import com.android.wm.shell.windowdecor.common.createRippleDrawable
+import com.android.wm.shell.windowdecor.common.createBackgroundDrawable
import com.android.wm.shell.windowdecor.extension.isLightCaptionBarAppearance
import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppearance
@@ -385,7 +379,7 @@ class AppHeaderViewHolder(
val colorStateList = ColorStateList.valueOf(foregroundColor).withAlpha(foregroundAlpha)
// App chip.
openMenuButton.apply {
- background = createRippleDrawable(
+ background = createBackgroundDrawable(
color = foregroundColor,
cornerRadius = headerButtonsRippleRadius,
drawableInsets = appChipDrawableInsets,
@@ -396,11 +390,12 @@ class AppHeaderViewHolder(
setTextColor(colorStateList)
}
appIconImageView.imageAlpha = foregroundAlpha
+ defaultFocusHighlightEnabled = false
}
// Minimize button.
minimizeWindowButton.apply {
imageTintList = colorStateList
- background = createRippleDrawable(
+ background = createBackgroundDrawable(
color = foregroundColor,
cornerRadius = headerButtonsRippleRadius,
drawableInsets = minimizeDrawableInsets
@@ -413,7 +408,7 @@ class AppHeaderViewHolder(
darkMode = header.appTheme == Theme.DARK,
iconForegroundColor = colorStateList,
baseForegroundColor = foregroundColor,
- rippleDrawable = createRippleDrawable(
+ backgroundDrawable = createBackgroundDrawable(
color = foregroundColor,
cornerRadius = headerButtonsRippleRadius,
drawableInsets = maximizeDrawableInsets
@@ -451,7 +446,7 @@ class AppHeaderViewHolder(
// Close button.
closeWindowButton.apply {
imageTintList = colorStateList
- background = createRippleDrawable(
+ background = createBackgroundDrawable(
color = foregroundColor,
cornerRadius = headerButtonsRippleRadius,
drawableInsets = closeDrawableInsets
@@ -471,11 +466,7 @@ class AppHeaderViewHolder(
override fun onHandleMenuOpened() {}
- override fun onHandleMenuClosed() {
- openMenuButton.post {
- openMenuButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
- }
- }
+ override fun onHandleMenuClosed() {}
fun onMaximizeWindowHoverExit() {
maximizeButtonView.cancelHoverAnimation()
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index 6a6aa1abc9f3..fa9864b539ee 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -17,15 +17,15 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.tools.NavBar
-import android.tools.Rotation
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
-import android.tools.helpers.WindowUtils
import android.tools.traces.parsers.WindowManagerStateHelper
import androidx.test.filters.RequiresDevice
+import androidx.test.uiautomator.UiDevice
import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils.isLeftRightSplit
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -37,6 +37,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
+ private val device = UiDevice.getInstance(instrumentation)
+
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
@@ -73,7 +75,8 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy
}
?: return@add false
- if (isLandscape(flicker.scenario.endRotation)) {
+ if (isLeftRightSplit(instrumentation.context, flicker.scenario.endRotation,
+ device.displaySizeDp)) {
return@add if (flicker.scenario.isTablet) {
secondaryAppWindow.frame.right <= primaryAppWindow.frame.left
} else {
@@ -109,7 +112,8 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy
val secondaryVisibleRegion =
secondaryAppLayer.visibleRegion?.bounds ?: return@add false
- if (isLandscape(flicker.scenario.endRotation)) {
+ if (isLeftRightSplit(instrumentation.context, flicker.scenario.endRotation,
+ device.displaySizeDp)) {
return@add if (flicker.scenario.isTablet) {
secondaryVisibleRegion.right <= primaryVisibleRegion.left
} else {
@@ -126,11 +130,6 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy
.waitForAndVerify()
}
- private fun isLandscape(rotation: Rotation): Boolean {
- val displayBounds = WindowUtils.getDisplayBounds(rotation)
- return displayBounds.width() > displayBounds.height()
- }
-
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
index 26203d4afccd..3fd93d3eaf59 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
@@ -17,16 +17,16 @@
package com.android.wm.shell.scenarios
import android.app.Instrumentation
-import android.graphics.Point
import android.tools.NavBar
import android.tools.Rotation
-import android.tools.helpers.WindowUtils
import android.tools.traces.parsers.WindowManagerStateHelper
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.launcher3.tapl.LauncherInstrumentation
import com.android.wm.shell.Utils
import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils.isLeftRightSplit
+import com.android.wm.shell.flicker.utils.SplitScreenUtils.isTablet
import org.junit.After
import org.junit.Before
import org.junit.Ignore
@@ -89,14 +89,14 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
}
?: return@add false
- if (isLandscape(rotation)) {
- return@add if (isTablet()) {
+ if (isLeftRightSplit(instrumentation.context, rotation, device.displaySizeDp)) {
+ return@add if (isTablet(device.displaySizeDp)) {
secondaryAppWindow.frame.right <= primaryAppWindow.frame.left
} else {
primaryAppWindow.frame.right <= secondaryAppWindow.frame.left
}
} else {
- return@add if (isTablet()) {
+ return@add if (isTablet(device.displaySizeDp)) {
primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
} else {
primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
@@ -125,14 +125,14 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
val secondaryVisibleRegion =
secondaryAppLayer.visibleRegion?.bounds ?: return@add false
- if (isLandscape(rotation)) {
- return@add if (isTablet()) {
+ if (isLeftRightSplit(instrumentation.context, rotation, device.displaySizeDp)) {
+ return@add if (isTablet(device.displaySizeDp)) {
secondaryVisibleRegion.right <= primaryVisibleRegion.left
} else {
primaryVisibleRegion.right <= secondaryVisibleRegion.left
}
} else {
- return@add if (isTablet()) {
+ return@add if (isTablet(device.displaySizeDp)) {
primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
} else {
primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
@@ -141,15 +141,4 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
}
.waitForAndVerify()
}
-
- private fun isLandscape(rotation: Rotation): Boolean {
- val displayBounds = WindowUtils.getDisplayBounds(rotation)
- return displayBounds.width() > displayBounds.height()
- }
-
- private fun isTablet(): Boolean {
- val sizeDp: Point = device.displaySizeDp
- val LARGE_SCREEN_DP_THRESHOLD = 600
- return sizeDp.x >= LARGE_SCREEN_DP_THRESHOLD && sizeDp.y >= LARGE_SCREEN_DP_THRESHOLD
- }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index feb3edc9dab7..49d6877a1654 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -17,12 +17,14 @@
package com.android.wm.shell.flicker.utils
import android.app.Instrumentation
+import android.content.Context
import android.graphics.Point
import android.os.SystemClock
import android.tools.Rotation
import android.tools.device.apphelpers.IStandardAppHelper
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.helpers.WindowUtils
import android.tools.traces.component.ComponentNameMatcher
import android.tools.traces.component.IComponentMatcher
import android.tools.traces.component.IComponentNameMatcher
@@ -393,4 +395,24 @@ object SplitScreenUtils {
error("Fail to copy content in split")
}
}
+
+ fun isLeftRightSplit(context: Context, rotation: Rotation, displaySizeDp: Point): Boolean {
+ val allowLeftRightSplit = context.resources.getBoolean(
+ com.android.internal.R.bool.config_leftRightSplitInPortrait)
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ val isLandscape = displayBounds.width() > displayBounds.height()
+ if (allowLeftRightSplit && isTablet(displaySizeDp)) {
+ // Certain devices allow left/right split in portrait, so they end up with top/bottom
+ // split in landscape
+ return !isLandscape
+ } else {
+ return isLandscape
+ }
+ }
+
+ fun isTablet(displaySizeDp: Point): Boolean {
+ val LARGE_SCREEN_DP_THRESHOLD = 600
+ return displaySizeDp.x >= LARGE_SCREEN_DP_THRESHOLD
+ && displaySizeDp.y >= LARGE_SCREEN_DP_THRESHOLD
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
index 42310caba1c6..925ca0f1638d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -35,6 +36,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.SurfaceControl;
@@ -138,13 +140,14 @@ public class BubbleTransitionsTest extends ShellTestCase {
return taskInfo;
}
- private TransitionInfo setupFullscreenTaskTransition(ActivityManager.RunningTaskInfo taskInfo) {
+ private TransitionInfo setupFullscreenTaskTransition(ActivityManager.RunningTaskInfo taskInfo,
+ SurfaceControl taskLeash, SurfaceControl snapshot) {
final TransitionInfo info = new TransitionInfo(TRANSIT_CONVERT_TO_BUBBLE, 0);
- final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token,
- mock(SurfaceControl.class));
+ final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash);
chg.setTaskInfo(taskInfo);
chg.setMode(TRANSIT_CHANGE);
chg.setStartAbsBounds(new Rect(0, 0, FULLSCREEN_TASK_WIDTH, FULLSCREEN_TASK_HEIGHT));
+ chg.setSnapshot(snapshot, /* luma= */ 0f);
info.addChange(chg);
info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0));
return info;
@@ -172,7 +175,9 @@ public class BubbleTransitionsTest extends ShellTestCase {
// Ensure we are communicating with the taskviewtransitions queue
assertTrue(mTaskViewTransitions.hasPending());
- final TransitionInfo info = setupFullscreenTaskTransition(taskInfo);
+ SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build();
+ SurfaceControl snapshot = new SurfaceControl.Builder().setName("snapshot").build();
+ final TransitionInfo info = setupFullscreenTaskTransition(taskInfo, taskLeash, snapshot);
SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
final boolean[] finishCalled = new boolean[]{false};
@@ -183,7 +188,8 @@ public class BubbleTransitionsTest extends ShellTestCase {
ctb.startAnimation(ctb.mTransition, info, startT, finishT, finishCb);
assertFalse(mTaskViewTransitions.hasPending());
- verify(startT).setPosition(any(), eq(0f), eq(0f));
+ verify(startT).setPosition(taskLeash, 0, 0);
+ verify(startT).setPosition(snapshot, 0, 0);
verify(mBubbleData).notificationEntryUpdated(eq(mBubble), anyBoolean(), anyBoolean());
@@ -194,7 +200,7 @@ public class BubbleTransitionsTest extends ShellTestCase {
// Check that preparing transition is not reset before continueExpand is called
verify(mBubble, never()).setPreparingTransition(any());
ArgumentCaptor<Runnable> animCb = ArgumentCaptor.forClass(Runnable.class);
- verify(mLayerView).animateConvert(any(), any(), any(), any(), animCb.capture());
+ verify(mLayerView).animateConvert(any(), any(), anyFloat(), any(), any(), animCb.capture());
// continueExpand is now called, check that preparing transition is cleared
ctb.continueExpand();
@@ -209,14 +215,14 @@ public class BubbleTransitionsTest extends ShellTestCase {
public void testConvertToBubble_drag() {
ActivityManager.RunningTaskInfo taskInfo = setupBubble();
- Rect draggedTaskBounds = new Rect(10, 20, 30, 40);
WindowContainerTransaction pendingWct = new WindowContainerTransaction();
WindowContainerToken pendingDragOpToken = createMockToken();
pendingWct.reorder(pendingDragOpToken, /* onTop= */ false);
+ PointF dragPosition = new PointF(10f, 20f);
BubbleTransitions.DragData dragData = new BubbleTransitions.DragData(
- draggedTaskBounds, pendingWct, /* releasedOnLeft= */ false
- );
+ /* releasedOnLeft= */ false, /* taskScale= */ 0.5f, /* cornerRadius= */ 10f,
+ dragPosition, pendingWct);
final BubbleTransitions.BubbleTransition bt = mBubbleTransitions.startConvertToBubble(
mBubble, taskInfo, mExpandedViewManager, mTaskViewFactory, mBubblePositioner,
@@ -234,15 +240,21 @@ public class BubbleTransitionsTest extends ShellTestCase {
== WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
&& op.getContainer() == pendingDragOpToken.asBinder())).isTrue();
- final TransitionInfo info = setupFullscreenTaskTransition(taskInfo);
+ SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build();
+ SurfaceControl snapshot = new SurfaceControl.Builder().setName("snapshot").build();
+ final TransitionInfo info = setupFullscreenTaskTransition(taskInfo, taskLeash, snapshot);
SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
Transitions.TransitionFinishCallback finishCb = wct -> {};
ctb.startAnimation(ctb.mTransition, info, startT, finishT, finishCb);
- // Verify that dragged task bounds are used for the position
- verify(startT).setPosition(any(), eq((float) draggedTaskBounds.left),
- eq((float) draggedTaskBounds.top));
+ // Verify that snapshot and task are placed at where the drag ended
+ verify(startT).setPosition(taskLeash, dragPosition.x, dragPosition.y);
+ verify(startT).setPosition(snapshot, dragPosition.x, dragPosition.y);
+ // Snapshot has the scale of the dragged task
+ verify(startT).setScale(snapshot, dragData.getTaskScale(), dragData.getTaskScale());
+ // Snapshot has dragged task corner radius
+ verify(startT).setCornerRadius(snapshot, dragData.getCornerRadius());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
index 01b76edd9b25..1066276becc7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
@@ -19,6 +19,8 @@ package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -128,6 +130,31 @@ public class PipBoundsStateTest extends ShellTestCase {
}
@Test
+ public void setLastPipComponentName_notChanged_doesNotCallbackComponentChangedListener() {
+ mPipBoundsState.setLastPipComponentName(mTestComponentName1);
+ PipBoundsState.OnPipComponentChangedListener mockListener =
+ mock(PipBoundsState.OnPipComponentChangedListener.class);
+
+ mPipBoundsState.addOnPipComponentChangedListener(mockListener);
+ mPipBoundsState.setLastPipComponentName(mTestComponentName1);
+
+ verify(mockListener, never()).onPipComponentChanged(any(), any());
+ }
+
+ @Test
+ public void setLastPipComponentName_changed_callbackComponentChangedListener() {
+ mPipBoundsState.setLastPipComponentName(mTestComponentName1);
+ PipBoundsState.OnPipComponentChangedListener mockListener =
+ mock(PipBoundsState.OnPipComponentChangedListener.class);
+
+ mPipBoundsState.addOnPipComponentChangedListener(mockListener);
+ mPipBoundsState.setLastPipComponentName(mTestComponentName2);
+
+ verify(mockListener).onPipComponentChanged(
+ eq(mTestComponentName1), eq(mTestComponentName2));
+ }
+
+ @Test
public void testSetLastPipComponentName_notChanged_doesNotClearReentryState() {
mPipBoundsState.setLastPipComponentName(mTestComponentName1);
mPipBoundsState.saveReentryState(DEFAULT_SNAP_FRACTION);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt
new file mode 100644
index 000000000000..fbc940663d19
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wm.shell.desktopmode
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.WindowManager
+import android.window.TransitionInfo
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.util.StubTransaction
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class DesktopModeMoveToDisplayTransitionHandlerTest : ShellTestCase() {
+ private lateinit var handler: DesktopModeMoveToDisplayTransitionHandler
+
+ @Before
+ fun setUp() {
+ handler = DesktopModeMoveToDisplayTransitionHandler(StubTransaction())
+ }
+
+ @Test
+ fun handleRequest_returnsNull() {
+ assertNull(handler.handleRequest(mock(), mock()))
+ }
+
+ @Test
+ fun startAnimation_changeWithinDisplay_returnsFalse() {
+ val animates =
+ handler.startAnimation(
+ transition = mock(),
+ info =
+ TransitionInfo(WindowManager.TRANSIT_CHANGE, /* flags= */ 0).apply {
+ addChange(
+ TransitionInfo.Change(mock(), mock()).apply { setDisplayId(1, 1) }
+ )
+ },
+ startTransaction = StubTransaction(),
+ finishTransaction = StubTransaction(),
+ finishCallback = mock(),
+ )
+
+ assertFalse("Should not animate open transition", animates)
+ }
+
+ @Test
+ fun startAnimation_changeMoveToDisplay_returnsTrue() {
+ val animates =
+ handler.startAnimation(
+ transition = mock(),
+ info =
+ TransitionInfo(WindowManager.TRANSIT_CHANGE, /* flags= */ 0).apply {
+ addChange(
+ TransitionInfo.Change(mock(), mock()).apply { setDisplayId(1, 2) }
+ )
+ },
+ startTransaction = StubTransaction(),
+ finishTransaction = StubTransaction(),
+ finishCallback = mock(),
+ )
+
+ assertTrue("Should animate display change transition", animates)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index dcc9e2415039..fe1dc29181b9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -20,6 +20,7 @@ import android.animation.AnimatorTestRule
import android.app.ActivityManager.RunningTaskInfo
import android.graphics.PointF
import android.graphics.Rect
+import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
@@ -28,6 +29,7 @@ import android.view.SurfaceControl
import androidx.test.filters.SmallTest
import com.android.internal.policy.SystemBarUtils
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
+import com.android.window.flags.Flags.FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
@@ -45,6 +47,8 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
/**
@@ -345,6 +349,38 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
assertThat(visualIndicator.indicatorBounds).isEqualTo(dropTargetBounds)
}
+ @Test
+ @DisableFlags(FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun createIndicator_inTransitionFlagDisabled_isAttachedToDisplayArea() {
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+
+ verify(taskDisplayAreaOrganizer).attachToDisplayArea(anyInt(), any())
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun createIndicator_fromFreeform_inTransitionFlagEnabled_isAttachedToDisplayArea() {
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
+
+ verify(taskDisplayAreaOrganizer).attachToDisplayArea(anyInt(), any())
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun createIndicator_fromFullscreen_inTransitionFlagEnabled_notAttachedToDisplayArea() {
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+
+ verify(taskDisplayAreaOrganizer, never()).attachToDisplayArea(anyInt(), any())
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun createIndicator_fromSplit_inTransitionFlagEnabled_notAttachedToDisplayArea() {
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+
+ verify(taskDisplayAreaOrganizer, never()).attachToDisplayArea(anyInt(), any())
+ }
+
private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) {
visualIndicator =
DesktopModeVisualIndicator(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index 2e74d4391c63..de92d391645a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -88,7 +88,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
datastoreScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
shellInit = spy(ShellInit(testExecutor))
- repo = DesktopRepository(persistentRepository, datastoreScope, DEFAULT_USER_ID)
+ repo = spy(DesktopRepository(persistentRepository, datastoreScope, DEFAULT_USER_ID))
whenever(runBlocking { persistentRepository.readDesktop(any(), any()) })
.thenReturn(Desktop.getDefaultInstance())
shellInit.init()
@@ -1171,6 +1171,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
val tasksBeforeRemoval = repo.removeDesk(deskId = DEFAULT_DISPLAY)
+ verify(repo, times(1)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
assertThat(tasksBeforeRemoval).containsExactly(1, 2, 3).inOrder()
assertThat(repo.getActiveTasks(displayId = DEFAULT_DISPLAY)).isEmpty()
}
@@ -1184,6 +1185,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
repo.removeDesk(deskId = 3)
+ verify(repo, times(1)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
assertThat(repo.getDeskIds(displayId = DEFAULT_DISPLAY)).doesNotContain(3)
}
@@ -1196,6 +1198,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
repo.removeDesk(deskId = 2)
+ verify(repo, times(1)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
assertThat(repo.getDeskIds(displayId = DEFAULT_DISPLAY)).doesNotContain(2)
}
@@ -1424,6 +1427,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
repo.removeDesk(deskId = 1)
executor.flushAll()
+ verify(repo, times(1)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
val lastRemoval = assertNotNull(listener.lastRemoval)
assertThat(lastRemoval.displayId).isEqualTo(0)
assertThat(lastRemoval.deskId).isEqualTo(1)
@@ -1440,6 +1444,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
repo.removeDesk(deskId = 2)
executor.flushAll()
+ verify(repo, times(0)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
assertThat(listener.lastRemoval).isNull()
}
@@ -1455,6 +1460,7 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
repo.removeDesk(deskId = 1)
executor.flushAll()
+ verify(repo, times(1)).notifyVisibleTaskListeners(DEFAULT_DISPLAY, visibleTasksCount = 0)
val lastActivationChange = assertNotNull(listener.lastActivationChange)
assertThat(lastActivationChange.displayId).isEqualTo(0)
assertThat(lastActivationChange.oldActive).isEqualTo(1)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
index 6b0ee5b7ffd4..4ace1b2d7c71 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
@@ -119,9 +119,8 @@ class DesktopTaskChangeListenerTest : ShellTestCase() {
}
@Test
- fun onTaskChanging_freeformTask_nonActiveTaskInDesktopRepo_addsTaskToDesktopRepo() {
+ fun onTaskChanging_freeformTask_addsTaskToDesktopRepo() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(false)
desktopTaskChangeListener.onTaskChanging(task)
@@ -129,28 +128,6 @@ class DesktopTaskChangeListenerTest : ShellTestCase() {
}
@Test
- fun onTaskChanging_freeformTask_activeVisibleTaskInDesktopRepo_updatesTaskVisibility() {
- val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(true)
-
- desktopTaskChangeListener.onTaskChanging(task)
-
- verify(desktopUserRepositories.current)
- .updateTask(task.displayId, task.taskId, task.isVisible)
- }
-
- @Test
- fun onTaskChanging_freeformTask_activeNonVisibleTask_updatesTaskVisibility() {
- val task = createFreeformTask().apply { isVisible = false }
- whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(true)
-
- desktopTaskChangeListener.onTaskChanging(task)
-
- verify(desktopUserRepositories.current)
- .updateTask(task.displayId, task.taskId, task.isVisible)
- }
-
- @Test
fun onTaskMovingToFront_fullscreenTask_activeTaskInDesktopRepo_removesTaskFromRepo() {
val task = createFullscreenTask().apply { isVisible = true }
whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(true)
@@ -180,6 +157,28 @@ class DesktopTaskChangeListenerTest : ShellTestCase() {
}
@Test
+ fun onTaskMovingToBack_activeTaskInRepo_updatesTask() {
+ val task = createFreeformTask().apply { isVisible = true }
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(true)
+
+ desktopTaskChangeListener.onTaskMovingToBack(task)
+
+ verify(desktopUserRepositories.current)
+ .updateTask(task.displayId, task.taskId, /* isVisible= */ false)
+ }
+
+ @Test
+ fun onTaskMovingToBack_nonActiveTaskInRepo_noop() {
+ val task = createFreeformTask().apply { isVisible = true }
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId)).thenReturn(false)
+
+ desktopTaskChangeListener.onTaskMovingToBack(task)
+
+ verify(desktopUserRepositories.current, never())
+ .updateTask(task.displayId, task.taskId, /* isVisible= */ false)
+ }
+
+ @Test
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
fun onTaskClosing_backNavEnabled_nonClosingTask_minimizesTaskInRepo() {
val task = createFreeformTask().apply { isVisible = true }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 8fdad0625556..87b7d344a3ec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -263,6 +263,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var mockDisplayContext: Context
@Mock private lateinit var dragToDisplayTransitionHandler: DragToDisplayTransitionHandler
+ @Mock
+ private lateinit var moveToDisplayTransitionHandler: DesktopModeMoveToDisplayTransitionHandler
private lateinit var controller: DesktopTasksController
private lateinit var shellInit: ShellInit
@@ -321,6 +323,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
transitions,
userRepositories,
shellTaskOrganizer,
+ desksOrganizer,
MAX_TASK_LIMIT,
mockInteractionJankMonitor,
mContext,
@@ -445,6 +448,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
userProfileContexts,
desktopModeCompatPolicy,
dragToDisplayTransitionHandler,
+ moveToDisplayTransitionHandler,
)
@After
@@ -2360,6 +2364,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveTaskToFront_postsWctWithReorderOp() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
@@ -2382,9 +2387,34 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun moveTaskToFront_bringsTasksOverLimit_minimizesBackTask() {
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveTaskToFront_reordersToFront() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ eq(TRANSIT_TO_FRONT),
+ any(),
+ eq(task1.taskId),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(Binder())
+
+ controller.moveTaskToFront(task1, remoteTransition = null)
+
+ verify(desksOrganizer).reorderTaskToFront(any(), eq(0), eq(task1))
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveTaskToFront_bringsTasksOverLimit_multiDesksDisabled_minimizesBackTask() {
setUpHomeTask()
- val freeformTasks = (1..MAX_TASK_LIMIT + 1).map { _ -> setUpFreeformTask() }
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT + 1).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
+ }
whenever(
desktopMixedTransitionHandler.startLaunchTransition(
eq(TRANSIT_TO_FRONT),
@@ -2405,6 +2435,32 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveTaskToFront_bringsTasksOverLimit_multiDesksEnabled_minimizesBackTask() {
+ val deskId = 0
+ setUpHomeTask()
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT + 1).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ eq(TRANSIT_TO_FRONT),
+ any(),
+ eq(freeformTasks[0].taskId),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(Binder())
+
+ controller.moveTaskToFront(freeformTasks[0], remoteTransition = null)
+
+ val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_TO_FRONT)
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[1])
+ }
+
+ @Test
fun moveTaskToFront_minimizedTask_marksTaskAsUnminimized() {
val transition = Binder()
val freeformTask = setUpFreeformTask()
@@ -2493,8 +2549,13 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun moveTaskToFront_backgroundTaskBringsTasksOverLimit_minimizesBackTask() {
- val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveTaskToFront_backgroundTaskBringsTasksOverLimit_multiDesksDisabled_minimizesBackTask() {
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
val task = createRecentTaskInfo(1001)
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(null)
whenever(
@@ -2517,11 +2578,38 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveTaskToFront_backgroundTaskBringsTasksOverLimit_multiDesksEnabled_minimizesBackTask() {
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
+ val task = createRecentTaskInfo(1001)
+ whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(null)
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ eq(TRANSIT_OPEN),
+ any(),
+ eq(task.taskId),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(Binder())
+
+ controller.moveTaskToFront(task.taskId, unminimizeReason = UnminimizeReason.UNKNOWN)
+
+ val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN)
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[0])
+ }
+
+ @Test
fun moveToNextDisplay_noOtherDisplays() {
whenever(rootTaskDisplayAreaOrganizer.displayIds).thenReturn(intArrayOf(DEFAULT_DISPLAY))
val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
controller.moveToNextDisplay(task.taskId)
- verifyWCTNotExecuted()
+ verify(transitions, never()).startTransition(anyInt(), any(), anyOrNull())
}
@Test
@@ -2539,9 +2627,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
val taskChange =
- getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
- it.container == task.token.asBinder() && it.isReparent
- }
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .hierarchyOps
+ .find { it.container == task.token.asBinder() && it.isReparent }
assertNotNull(taskChange)
assertThat(taskChange.newParent).isEqualTo(secondDisplayArea.token.asBinder())
assertThat(taskChange.toTop).isTrue()
@@ -2562,9 +2653,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
val taskChange =
- getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
- it.container == task.token.asBinder() && it.isReparent
- }
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .hierarchyOps
+ .find { it.container == task.token.asBinder() && it.isReparent }
assertNotNull(taskChange)
assertThat(taskChange.newParent).isEqualTo(defaultDisplayArea.token.asBinder())
assertThat(taskChange.toTop).isTrue()
@@ -2589,7 +2683,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
- with(getLatestWct(type = TRANSIT_CHANGE)) {
+ with(
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ ) {
val wallpaperChange =
hierarchyOps.find { op -> op.container == wallpaperToken.asBinder() }
assertNotNull(wallpaperChange)
@@ -2615,9 +2714,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
val wallpaperChange =
- getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find { op ->
- op.container == wallpaperToken.asBinder()
- }
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .hierarchyOps
+ .find { op -> op.container == wallpaperToken.asBinder() }
assertNotNull(wallpaperChange)
assertThat(wallpaperChange.type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
}
@@ -2649,7 +2751,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
- val taskChange = getLatestWct(type = TRANSIT_CHANGE).changes[task.token.asBinder()]
+ val taskChange =
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .changes[task.token.asBinder()]
assertNotNull(taskChange)
// To preserve DP size, pixel size is changed to 320x240. The ratio of the left margin
// to the right margin and the ratio of the top margin to bottom margin are also
@@ -2686,7 +2793,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
- val taskChange = getLatestWct(type = TRANSIT_CHANGE).changes[task.token.asBinder()]
+ val taskChange =
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .changes[task.token.asBinder()]
assertNotNull(taskChange)
assertThat(taskChange.configuration.windowConfiguration.bounds)
.isEqualTo(Rect(960, 480, 1280, 720))
@@ -2717,7 +2829,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
- val taskChange = getLatestWct(type = TRANSIT_CHANGE).changes[task.token.asBinder()]
+ val taskChange =
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .changes[task.token.asBinder()]
assertNotNull(taskChange)
// DP size is preserved. The window is centered in the destination display.
assertThat(taskChange.configuration.windowConfiguration.bounds)
@@ -2755,7 +2872,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
- val taskChange = getLatestWct(type = TRANSIT_CHANGE).changes[task.token.asBinder()]
+ val taskChange =
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .changes[task.token.asBinder()]
assertNotNull(taskChange)
assertThat(taskChange.configuration.windowConfiguration.bounds.left).isAtLeast(0)
assertThat(taskChange.configuration.windowConfiguration.bounds.top).isAtLeast(0)
@@ -2782,9 +2904,14 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
controller.moveToNextDisplay(task.taskId)
val taskChange =
- getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
- it.container == task.token.asBinder() && it.type == HIERARCHY_OP_TYPE_REORDER
- }
+ getLatestWct(
+ type = TRANSIT_CHANGE,
+ handlerClass = DesktopModeMoveToDisplayTransitionHandler::class.java,
+ )
+ .hierarchyOps
+ .find {
+ it.container == task.token.asBinder() && it.type == HIERARCHY_OP_TYPE_REORDER
+ }
assertNotNull(taskChange)
assertThat(taskChange.toTop).isTrue()
assertThat(taskChange.includingParents()).isTrue()
@@ -3488,7 +3615,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun handleRequest_fullscreenTaskToFreeform_underTaskLimit_dontMinimize() {
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskToDesk_underTaskLimit_multiDesksDisabled_dontMinimize() {
val freeformTask = setUpFreeformTask()
markTaskVisible(freeformTask)
val fullscreenTask = createFullscreenTask()
@@ -3501,7 +3629,29 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun handleRequest_fullscreenTaskToFreeform_bringsTasksOverLimit_otherTaskIsMinimized() {
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskToDesk_underTaskLimit_multiDesksEnabled_dontMinimize() {
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val freeformTask =
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId).also {
+ markTaskVisible(it)
+ }
+
+ // Launch a fullscreen task while in the desk.
+ val fullscreenTask = createFullscreenTask()
+ val transition = Binder()
+ val wct = controller.handleRequest(transition, createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ verify(desksOrganizer, never()).minimizeTask(eq(wct), eq(deskId), any())
+ assertNull(desktopTasksLimiter.getMinimizingTask(transition))
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskToDesk_bringsTasksOverLimit_multiDesksDisabled_otherTaskIsMinimized() {
val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
freeformTasks.forEach { markTaskVisible(it) }
val fullscreenTask = createFullscreenTask()
@@ -3515,7 +3665,34 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun handleRequest_fullscreenTaskWithTaskOnHome_bringsTasksOverLimit_otherTaskIsMinimized() {
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskToDesk_bringsTasksOverLimit_multiDesksEnabled_otherTaskIsMinimized() {
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId).also {
+ markTaskVisible(it)
+ }
+ }
+
+ // Launch a fullscreen task while in the desk.
+ setUpHomeTask()
+ val fullscreenTask = createFullscreenTask()
+ val transition = Binder()
+ val wct = controller.handleRequest(transition, createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[0])
+ val minimizingTask =
+ assertNotNull(desktopTasksLimiter.getMinimizingTask(transition)?.taskId)
+ assertThat(minimizingTask).isEqualTo(freeformTasks[0].taskId)
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskWithTaskOnHome_bringsTasksOverLimit_multiDesksDisabled_otherTaskIsMinimized() {
val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
freeformTasks.forEach { markTaskVisible(it) }
val fullscreenTask = createFullscreenTask()
@@ -3524,13 +3701,43 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
// Make sure we reorder the new task to top, and the back task to the bottom
- assertThat(wct!!.hierarchyOps.size).isEqualTo(9)
+ assertThat(wct!!.hierarchyOps.size).isEqualTo(8)
wct.assertReorderAt(0, fullscreenTask, toTop = true)
- wct.assertReorderAt(8, freeformTasks[0], toTop = false)
+ // Oldest task that needs to minimized is never reordered to top over Home.
+ val taskToMinimize = freeformTasks[0]
+ wct.assertWithoutHop { hop ->
+ hop.container == taskToMinimize.token &&
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ hop.toTop == true
+ }
}
@Test
- fun handleRequest_fullscreenTaskWithTaskOnHome_beyondLimit_existingAndNewTasksAreMinimized() {
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskWithTaskOnHome_bringsTasksOverLimit_multiDesksEnabled_otherTaskIsMinimized() {
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
+ freeformTasks.forEach { markTaskVisible(it) }
+ val fullscreenTask = createFullscreenTask()
+ fullscreenTask.baseIntent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME)
+
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ // The launching task is moved to the desk.
+ verify(desksOrganizer).moveTaskToDesk(wct, deskId, fullscreenTask)
+ // The bottom-most task is minimized.
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[0])
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskWithTaskOnHome_beyondLimit_multiDesksDisabled_existingAndNewTasksAreMinimized() {
val minimizedTask = setUpFreeformTask()
taskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = minimizedTask.taskId)
val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
@@ -3541,12 +3748,100 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
- assertThat(wct!!.hierarchyOps.size).isEqualTo(10)
+ assertThat(wct!!.hierarchyOps.size).isEqualTo(9)
wct.assertReorderAt(0, fullscreenTask, toTop = true)
// Make sure we reorder the home task to the top, desktop tasks to top of them and minimized
// task is under the home task.
wct.assertReorderAt(1, homeTask, toTop = true)
- wct.assertReorderAt(9, freeformTasks[0], toTop = false)
+ // Oldest task that needs to minimized is never reordered to top over Home.
+ val taskToMinimize = freeformTasks[0]
+ wct.assertWithoutHop { hop ->
+ hop.container == taskToMinimize.token &&
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ hop.toTop == true
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskWithTaskOnHome_beyondLimit_multiDesksEnabled_existingAndNewTasksAreMinimized() {
+ // A desk with a minimized tasks, and non-minimized tasks already at the task limit.
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val minimizedTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.minimizeTaskInDesk(
+ displayId = DEFAULT_DISPLAY,
+ deskId = deskId,
+ taskId = minimizedTask.taskId,
+ )
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId).also {
+ markTaskVisible(it)
+ }
+ }
+
+ // Launch a fullscreen task that brings Home to front with it.
+ setUpHomeTask()
+ val fullscreenTask = createFullscreenTask()
+ fullscreenTask.baseIntent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME)
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[0])
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_fullscreenTaskWithTaskOnHome_taskAddedToDesk() {
+ // A desk with a minimized tasks, and non-minimized tasks already at the task limit.
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+
+ // Launch a fullscreen task that brings Home to front with it.
+ setUpHomeTask()
+ val fullscreenTask = createFullscreenTask()
+ fullscreenTask.baseIntent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME)
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ verify(desksOrganizer).moveTaskToDesk(wct, deskId, fullscreenTask)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ )
+ fun handleRequest_fullscreenTaskWithTaskOnHome_activatesDesk() {
+ val deskId = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+
+ // Launch a fullscreen task that brings Home to front with it.
+ val homeTask = setUpHomeTask()
+ val fullscreenTask = createFullscreenTask()
+ fullscreenTask.baseIntent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME)
+ val transition = Binder()
+ val wct = controller.handleRequest(transition, createTransition(fullscreenTask))
+
+ assertNotNull(wct)
+ wct.assertReorder(homeTask, toTop = true)
+ wct.assertReorder(wallpaperToken, toTop = true)
+ verify(desksOrganizer).activateDesk(wct, deskId)
+ verify(desksTransitionsObserver)
+ .addPendingTransition(
+ DeskTransition.ActiveDeskWithTask(
+ token = transition,
+ displayId = DEFAULT_DISPLAY,
+ deskId = deskId,
+ enterTaskId = fullscreenTask.taskId,
+ )
+ )
}
@Test
@@ -3609,8 +3904,13 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_minimize() {
- val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_multiDesksDisabled_minimize() {
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
freeformTasks.forEach { markTaskVisible(it) }
val newFreeformTask = createFreeformTask()
@@ -3623,6 +3923,24 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@Test
@EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_multiDesksEnabled_minimize() {
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
+ freeformTasks.forEach { markTaskVisible(it) }
+ val newFreeformTask = createFreeformTask()
+
+ val wct =
+ controller.handleRequest(Binder(), createTransition(newFreeformTask, TRANSIT_OPEN))
+
+ assertNotNull(wct)
+ verify(desksOrganizer).minimizeTask(wct, deskId, freeformTasks[0])
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun handleRequest_freeformTaskFromInactiveDesk_tracksDeskDeactivation() {
val deskId = 0
val freeformTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
@@ -5524,7 +5842,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES)
- fun openInstance_fromFreeformAddsNewWindow() {
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun openInstance_fromFreeformAddsNewWindow_multiDesksDisabled() {
setUpLandscapeDisplay()
val task = setUpFreeformTask()
val taskToRequest = setUpFreeformTask()
@@ -5538,7 +5857,9 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
)
.thenReturn(Binder())
+
runOpenInstance(task, taskToRequest.taskId)
+
verify(desktopMixedTransitionHandler)
.startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull())
val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_TO_FRONT)
@@ -5547,10 +5868,42 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun openInstance_fromFreeformAddsNewWindow_multiDesksEnabled() {
+ setUpLandscapeDisplay()
+ val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
+ val taskToRequest = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0)
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ eq(TRANSIT_TO_FRONT),
+ any(),
+ eq(taskToRequest.taskId),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(Binder())
+
+ runOpenInstance(task, taskToRequest.taskId)
+
+ verify(desktopMixedTransitionHandler)
+ .startLaunchTransition(anyInt(), any(), anyInt(), anyOrNull(), anyOrNull())
+ verify(desksOrganizer).reorderTaskToFront(any(), eq(0), eq(taskToRequest))
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES)
- fun openInstance_fromFreeform_minimizesIfNeeded() {
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun openInstance_fromFreeform_multiDesksDisabled_minimizesIfNeeded() {
setUpLandscapeDisplay()
- val freeformTasks = (1..MAX_TASK_LIMIT + 1).map { _ -> setUpFreeformTask() }
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT + 1).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
val oldestTask = freeformTasks.first()
val newestTask = freeformTasks.last()
@@ -5576,6 +5929,40 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun openInstance_fromFreeform_multiDesksEnabled_minimizesIfNeeded() {
+ setUpLandscapeDisplay()
+ val deskId = 0
+ val freeformTasks =
+ (1..MAX_TASK_LIMIT + 1).map { _ ->
+ setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ }
+ val oldestTask = freeformTasks.first()
+ val newestTask = freeformTasks.last()
+
+ val transition = Binder()
+ val wctCaptor = argumentCaptor<WindowContainerTransaction>()
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ anyInt(),
+ wctCaptor.capture(),
+ anyInt(),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(transition)
+
+ runOpenInstance(newestTask, freeformTasks[1].taskId)
+
+ val wct = wctCaptor.firstValue
+ verify(desksOrganizer).minimizeTask(wct, deskId, oldestTask)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES)
fun openInstance_fromFreeform_exitsImmersiveIfNeeded() {
setUpLandscapeDisplay()
@@ -6533,7 +6920,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
)
fun startLaunchTransition_desktopNotShowing_movesWallpaperToFront() {
- val launchingTask = createFreeformTask()
+ val launchingTask = createFreeformTask(displayId = DEFAULT_DISPLAY)
val wct = WindowContainerTransaction()
wct.reorder(launchingTask.token, /* onTop= */ true)
whenever(
@@ -6547,7 +6934,13 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
.thenReturn(Binder())
- controller.startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
+ controller.startLaunchTransition(
+ transitionType = TRANSIT_OPEN,
+ wct = wct,
+ launchingTaskId = null,
+ deskId = 0,
+ displayId = DEFAULT_DISPLAY,
+ )
val latestWct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN)
val launchingTaskReorderIndex = latestWct.indexOfReorder(launchingTask, toTop = true)
@@ -6571,6 +6964,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
transitionType = TRANSIT_OPEN,
wct = WindowContainerTransaction(),
launchingTaskId = null,
+ deskId = 0,
+ displayId = DEFAULT_DISPLAY,
)
verify(desktopModeEnterExitTransitionListener).onEnterDesktopModeTransitionStarted(any())
@@ -6580,6 +6975,51 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@EnableFlags(
Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun startLaunchTransition_launchingTaskFromInactiveDesk_otherDeskActive_activatesDesk() {
+ val activeDeskId = 4
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = activeDeskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = activeDeskId)
+ val inactiveDesk = 5
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = inactiveDesk)
+ val launchingTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = inactiveDesk)
+ val transition = Binder()
+ whenever(
+ desktopMixedTransitionHandler.startLaunchTransition(
+ eq(TRANSIT_OPEN),
+ any(),
+ eq(launchingTask.taskId),
+ anyOrNull(),
+ anyOrNull(),
+ )
+ )
+ .thenReturn(transition)
+
+ val wct = WindowContainerTransaction()
+ controller.startLaunchTransition(
+ transitionType = TRANSIT_OPEN,
+ wct = wct,
+ launchingTaskId = launchingTask.taskId,
+ deskId = inactiveDesk,
+ displayId = DEFAULT_DISPLAY,
+ )
+
+ verify(desksOrganizer).activateDesk(any(), eq(inactiveDesk))
+ verify(desksTransitionsObserver)
+ .addPendingTransition(
+ DeskTransition.ActivateDesk(
+ token = transition,
+ displayId = DEFAULT_DISPLAY,
+ deskId = inactiveDesk,
+ )
+ )
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
)
fun startLaunchTransition_desktopShowing_doesNotReorderWallpaper() {
val wct = WindowContainerTransaction()
@@ -6594,8 +7034,14 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
.thenReturn(Binder())
- setUpFreeformTask()
- controller.startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null)
+ setUpFreeformTask(deskId = 0, displayId = DEFAULT_DISPLAY)
+ controller.startLaunchTransition(
+ transitionType = TRANSIT_OPEN,
+ wct = wct,
+ launchingTaskId = null,
+ deskId = 0,
+ displayId = DEFAULT_DISPLAY,
+ )
val latestWct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN)
assertNull(latestWct.hierarchyOps.find { op -> op.container == wallpaperToken.asBinder() })
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 62e3c544e390..eeecb00b5b08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -39,12 +39,14 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+import com.android.window.flags.Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -67,10 +69,13 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.any
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
import org.mockito.quality.Strictness
/**
@@ -84,6 +89,7 @@ import org.mockito.quality.Strictness
class DesktopTasksLimiterTest : ShellTestCase() {
@Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
+ @Mock lateinit var desksOrganizer: DesksOrganizer
@Mock lateinit var transitions: Transitions
@Mock lateinit var interactionJankMonitor: InteractionJankMonitor
@Mock lateinit var handler: Handler
@@ -128,6 +134,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
transitions,
userRepositories,
shellTaskOrganizer,
+ desksOrganizer,
MAX_TASK_LIMIT,
interactionJankMonitor,
mContext,
@@ -148,6 +155,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
transitions,
userRepositories,
shellTaskOrganizer,
+ desksOrganizer,
0,
interactionJankMonitor,
mContext,
@@ -163,6 +171,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
transitions,
userRepositories,
shellTaskOrganizer,
+ desksOrganizer,
-5,
interactionJankMonitor,
mContext,
@@ -172,6 +181,21 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
+ fun createDesktopTasksLimiter_withNoLimit_shouldSucceed() {
+ // Instantiation should succeed without an error.
+ DesktopTasksLimiter(
+ transitions,
+ userRepositories,
+ shellTaskOrganizer,
+ desksOrganizer,
+ maxTasksLimit = null,
+ interactionJankMonitor,
+ mContext,
+ handler,
+ )
+ }
+
+ @Test
fun addPendingMinimizeTransition_taskIsNotMinimized() {
desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
@@ -380,7 +404,8 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
- fun addAndGetMinimizeTaskChanges_tasksWithinLimit_noTaskMinimized() {
+ @DisableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_tasksWithinLimit_multiDesksDisabled_noTaskMinimized() {
desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
(1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
@@ -388,7 +413,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
val wct = WindowContainerTransaction()
val minimizedTaskId =
desktopTasksLimiter.addAndGetMinimizeTaskChanges(
- displayId = DEFAULT_DISPLAY,
+ deskId = 0,
wct = wct,
newFrontTaskId = setUpFreeformTask().taskId,
)
@@ -398,7 +423,27 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
- fun addAndGetMinimizeTaskChanges_tasksAboveLimit_backTaskMinimized() {
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_tasksWithinLimit_multiDesksEnabled_noTaskMinimized() {
+ desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ (1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
+
+ val wct = WindowContainerTransaction()
+ val minimizedTaskId =
+ desktopTasksLimiter.addAndGetMinimizeTaskChanges(
+ deskId = 0,
+ wct = wct,
+ newFrontTaskId = setUpFreeformTask().taskId,
+ )
+
+ assertThat(minimizedTaskId).isNull()
+ verify(desksOrganizer, never()).minimizeTask(eq(wct), eq(0), any())
+ }
+
+ @Test
+ @DisableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_tasksAboveLimit_multiDesksDisabled_backTaskMinimized() {
desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
// The following list will be ordered bottom -> top, as the last task is moved to top last.
@@ -407,7 +452,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
val wct = WindowContainerTransaction()
val minimizedTaskId =
desktopTasksLimiter.addAndGetMinimizeTaskChanges(
- displayId = DEFAULT_DISPLAY,
+ deskId = DEFAULT_DISPLAY,
wct = wct,
newFrontTaskId = setUpFreeformTask().taskId,
)
@@ -419,7 +464,28 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
- fun addAndGetMinimizeTaskChanges_nonMinimizedTasksWithinLimit_noTaskMinimized() {
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_tasksAboveLimit_multiDesksEnabled_backTaskMinimized() {
+ desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ // The following list will be ordered bottom -> top, as the last task is moved to top last.
+ val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
+
+ val wct = WindowContainerTransaction()
+ val minimizedTaskId =
+ desktopTasksLimiter.addAndGetMinimizeTaskChanges(
+ deskId = DEFAULT_DISPLAY,
+ wct = wct,
+ newFrontTaskId = setUpFreeformTask().taskId,
+ )
+
+ assertThat(minimizedTaskId).isEqualTo(tasks.first().taskId)
+ verify(desksOrganizer).minimizeTask(wct, deskId = 0, tasks.first())
+ }
+
+ @Test
+ @DisableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_nonMinimizedTasksWithinLimit_multiDesksDisabled_noTaskMinimized() {
desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
@@ -428,7 +494,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
val wct = WindowContainerTransaction()
val minimizedTaskId =
desktopTasksLimiter.addAndGetMinimizeTaskChanges(
- displayId = 0,
+ deskId = 0,
wct = wct,
newFrontTaskId = setUpFreeformTask().taskId,
)
@@ -438,6 +504,26 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun addAndGetMinimizeTaskChanges_nonMinimizedTasksWithinLimit_multiDesksEnabled_noTaskMinimized() {
+ desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
+ val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
+ desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = tasks[0].taskId)
+
+ val wct = WindowContainerTransaction()
+ val minimizedTaskId =
+ desktopTasksLimiter.addAndGetMinimizeTaskChanges(
+ deskId = 0,
+ wct = wct,
+ newFrontTaskId = setUpFreeformTask().taskId,
+ )
+
+ assertThat(minimizedTaskId).isNull()
+ verify(desksOrganizer, never()).minimizeTask(eq(wct), eq(0), any())
+ }
+
+ @Test
fun getTaskToMinimize_tasksWithinLimit_returnsNull() {
desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0)
@@ -471,6 +557,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
transitions,
userRepositories,
shellTaskOrganizer,
+ desksOrganizer,
MAX_TASK_LIMIT2,
interactionJankMonitor,
mContext,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
index fd8842b6d99b..a7dc706eb6c9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
@@ -48,13 +48,11 @@ import com.android.wm.shell.back.BackAnimationController
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
-import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP
import com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP
-import com.android.wm.shell.util.StubTransaction
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
@@ -95,7 +93,6 @@ class DesktopTasksTransitionObserverTest {
private val backAnimationController = mock<BackAnimationController>()
private val desktopWallpaperActivityTokenProvider =
mock<DesktopWallpaperActivityTokenProvider>()
- private val desksTransitionObserver = mock<DesksTransitionObserver>()
private val wallpaperToken = MockToken().token()
private lateinit var transitionObserver: DesktopTasksTransitionObserver
@@ -119,7 +116,6 @@ class DesktopTasksTransitionObserverTest {
mixedHandler,
backAnimationController,
desktopWallpaperActivityTokenProvider,
- desksTransitionObserver,
shellInit,
)
}
@@ -403,21 +399,6 @@ class DesktopTasksTransitionObserverTest {
verify(taskRepository).setTaskInPip(task.displayId, task.taskId, enterPip = false)
}
- @Test
- fun onTransitionReady_forwardsToDesksTransitionObserver() {
- val transition = Binder()
- val info = TransitionInfo(TRANSIT_CLOSE, /* flags= */ 0)
-
- transitionObserver.onTransitionReady(
- transition = transition,
- info = info,
- StubTransaction(),
- StubTransaction(),
- )
-
- verify(desksTransitionObserver).onTransitionReady(transition, info)
- }
-
private fun createBackNavigationTransition(
task: RunningTaskInfo?,
type: Int = TRANSIT_TO_BACK,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index de55db86d1e7..0871d38ceb46 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -11,6 +11,8 @@ import android.graphics.PointF
import android.graphics.Rect
import android.os.IBinder
import android.os.SystemProperties
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.SurfaceControl
@@ -23,6 +25,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_HOLD
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE
import com.android.internal.jank.InteractionJankMonitor
+import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
@@ -78,6 +81,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
@Mock private lateinit var homeTaskLeash: SurfaceControl
@Mock private lateinit var desktopUserRepositories: DesktopUserRepositories
@Mock private lateinit var bubbleController: BubbleController
+ @Mock private lateinit var visualIndicator: DesktopModeVisualIndicator
private val transactionSupplier = Supplier { mock<SurfaceControl.Transaction>() }
@@ -740,11 +744,47 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
assertThat(fraction).isWithin(TOLERANCE).of(0f)
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun startDrag_indicatorFlagEnabled_attachesIndicatorToTransitionRoot() {
+ val task = createTask()
+ val rootLeash = mock<SurfaceControl>()
+ val startTransaction = mock<SurfaceControl.Transaction>()
+ startDrag(
+ defaultHandler,
+ task,
+ startTransaction = startTransaction,
+ transitionRootLeash = rootLeash,
+ )
+
+ verify(visualIndicator).reparentLeash(startTransaction, rootLeash)
+ verify(visualIndicator).fadeInIndicator()
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX)
+ fun startDrag_indicatorFlagDisabled_doesNotAttachIndicatorToTransitionRoot() {
+ val task = createTask()
+ val rootLeash = mock<SurfaceControl>()
+ val startTransaction = mock<SurfaceControl.Transaction>()
+ startDrag(
+ defaultHandler,
+ task,
+ startTransaction = startTransaction,
+ transitionRootLeash = rootLeash,
+ )
+
+ verify(visualIndicator, never()).reparentLeash(any(), any())
+ verify(visualIndicator, never()).fadeInIndicator()
+ }
+
private fun startDrag(
handler: DragToDesktopTransitionHandler,
task: RunningTaskInfo = createTask(),
+ startTransaction: SurfaceControl.Transaction = mock(),
finishTransaction: SurfaceControl.Transaction = mock(),
homeChange: TransitionInfo.Change? = createHomeChange(),
+ transitionRootLeash: SurfaceControl = mock(),
): IBinder {
whenever(dragAnimator.position).thenReturn(PointF())
// Simulate transition is started and is ready to animate.
@@ -756,8 +796,9 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
type = TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP,
draggedTask = task,
homeChange = homeChange,
+ rootLeash = transitionRootLeash,
),
- startTransaction = mock(),
+ startTransaction = startTransaction,
finishTransaction = finishTransaction,
finishCallback = {},
)
@@ -778,7 +819,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
)
)
.thenReturn(token)
- handler.startDragToDesktopTransition(task, dragAnimator)
+ handler.startDragToDesktopTransition(task, dragAnimator, visualIndicator)
return token
}
@@ -845,6 +886,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
type: Int,
draggedTask: RunningTaskInfo,
homeChange: TransitionInfo.Change? = createHomeChange(),
+ rootLeash: SurfaceControl = mock(),
) =
TransitionInfo(type, /* flags= */ 0).apply {
homeChange?.let { addChange(it) }
@@ -861,6 +903,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
flags = flags or FLAG_IS_WALLPAPER
}
)
+ addRootLeash(draggedTask.displayId, rootLeash, /* offsetLeft= */ 0, /* offsetTop= */ 0)
}
private fun createHomeChange() =
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
index 4c8cb3823f7e..c7518d5914b4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
@@ -25,6 +25,7 @@ import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.View
@@ -49,6 +50,8 @@ import org.mockito.Mockito.mock
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyZeroInteractions
@@ -121,7 +124,7 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
)
desktopExecutor.flushAll()
- verify(spyViewContainer).fadeInIndicator(any(), any(), any(), any())
+ verify(spyViewContainer).fadeInIndicatorInternal(any(), any(), any(), any())
}
@Test
@@ -265,6 +268,35 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
)
}
+ @Test
+ fun fadeInIndicator_callsFadeIn() {
+ val spyViewContainer = setupSpyViewContainer()
+
+ spyViewContainer.fadeInIndicator(
+ mock<DisplayLayout>(),
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
+ DEFAULT_DISPLAY,
+ )
+ desktopExecutor.flushAll()
+
+ verify(spyViewContainer).fadeInIndicatorInternal(any(), any(), any(), any())
+ }
+
+ @Test
+ fun fadeInIndicator_alreadyReleased_doesntCallFadeIn() {
+ val spyViewContainer = setupSpyViewContainer()
+ spyViewContainer.releaseVisualIndicator()
+
+ spyViewContainer.fadeInIndicator(
+ mock<DisplayLayout>(),
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
+ DEFAULT_DISPLAY,
+ )
+ desktopExecutor.flushAll()
+
+ verify(spyViewContainer, never()).fadeInIndicatorInternal(any(), any(), any(), any())
+ }
+
private fun setupSpyViewContainer(): VisualIndicatorViewContainer {
val viewContainer =
VisualIndicatorViewContainer(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
index 96b85ad2729e..891a1f1685cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
@@ -21,9 +21,11 @@ import android.view.Display
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.window.TransitionInfo
+import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
import android.window.WindowContainerTransaction.Change
import android.window.WindowContainerTransaction.HierarchyOp
+import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTaskOrganizer
@@ -473,14 +475,7 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
organizer.minimizeTask(wct, deskId = desk.deskRoot.deskId, task)
- assertThat(
- wct.hierarchyOps.any { hop ->
- hop.isReparent &&
- hop.container == task.token.asBinder() &&
- hop.newParent == desk.minimizationRoot.token.asBinder()
- }
- )
- .isTrue()
+ assertThat(wct.hasMinimizationHops(desk, task.token)).isTrue()
}
@Test
@@ -508,6 +503,110 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
assertThat(wct.isEmpty).isTrue()
}
+ @Test
+ fun unminimizeTask() {
+ val desk = createDesk()
+ val task = createFreeformTask().apply { parentTaskId = desk.deskRoot.deskId }
+ val wct = WindowContainerTransaction()
+ organizer.moveTaskToDesk(wct, desk.deskRoot.deskId, task)
+ organizer.onTaskAppeared(task, SurfaceControl())
+ organizer.minimizeTask(wct, deskId = desk.deskRoot.deskId, task)
+ task.parentTaskId = desk.minimizationRoot.rootId
+ organizer.onTaskInfoChanged(task)
+
+ wct.clear()
+ organizer.unminimizeTask(wct, deskId = desk.deskRoot.deskId, task)
+
+ assertThat(wct.hasUnminimizationHops(desk, task.token)).isTrue()
+ }
+
+ @Test
+ fun unminimizeTask_alreadyUnminimized_noOp() {
+ val desk = createDesk()
+ val task = createFreeformTask().apply { parentTaskId = desk.deskRoot.deskId }
+ val wct = WindowContainerTransaction()
+ organizer.moveTaskToDesk(wct, desk.deskRoot.deskId, task)
+ organizer.onTaskAppeared(task, SurfaceControl())
+
+ wct.clear()
+ organizer.unminimizeTask(wct, deskId = desk.deskRoot.deskId, task)
+
+ assertThat(wct.hasUnminimizationHops(desk, task.token)).isFalse()
+ }
+
+ @Test
+ fun unminimizeTask_notInDesk_noOp() {
+ val desk = createDesk()
+ val task = createFreeformTask()
+ val wct = WindowContainerTransaction()
+
+ organizer.unminimizeTask(wct, deskId = desk.deskRoot.deskId, task)
+
+ assertThat(wct.hasUnminimizationHops(desk, task.token)).isFalse()
+ }
+
+ @Test
+ fun reorderTaskToFront() {
+ val desk = createDesk()
+ val task = createFreeformTask().apply { parentTaskId = desk.deskRoot.deskId }
+ val wct = WindowContainerTransaction()
+ organizer.onTaskAppeared(task, SurfaceControl())
+
+ organizer.reorderTaskToFront(wct, desk.deskRoot.deskId, task)
+
+ assertThat(
+ wct.hierarchyOps.singleOrNull { hop ->
+ hop.container == task.token.asBinder() &&
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ hop.toTop &&
+ hop.includingParents()
+ }
+ )
+ .isNotNull()
+ }
+
+ @Test
+ fun reorderTaskToFront_notInDesk_noOp() {
+ val desk = createDesk()
+ val task = createFreeformTask()
+ val wct = WindowContainerTransaction()
+
+ organizer.reorderTaskToFront(wct, desk.deskRoot.deskId, task)
+
+ assertThat(
+ wct.hierarchyOps.singleOrNull { hop ->
+ hop.container == task.token.asBinder() &&
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ hop.toTop &&
+ hop.includingParents()
+ }
+ )
+ .isNull()
+ }
+
+ @Test
+ fun reorderTaskToFront_minimized_unminimizesAndReorders() {
+ val desk = createDesk()
+ val task = createFreeformTask().apply { parentTaskId = desk.deskRoot.deskId }
+ val wct = WindowContainerTransaction()
+ organizer.onTaskAppeared(task, SurfaceControl())
+ task.parentTaskId = desk.minimizationRoot.rootId
+ organizer.onTaskInfoChanged(task)
+
+ organizer.reorderTaskToFront(wct, desk.deskRoot.deskId, task)
+
+ assertThat(wct.hasUnminimizationHops(desk, task.token)).isTrue()
+ assertThat(
+ wct.hierarchyOps.singleOrNull { hop ->
+ hop.container == task.token.asBinder() &&
+ hop.type == HIERARCHY_OP_TYPE_REORDER &&
+ hop.toTop &&
+ hop.includingParents()
+ }
+ )
+ .isNotNull()
+ }
+
private data class DeskRoots(
val deskRoot: DeskRoot,
val minimizationRoot: DeskMinimizationRoot,
@@ -525,6 +624,27 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
)
}
+ private fun WindowContainerTransaction.hasMinimizationHops(
+ desk: DeskRoots,
+ task: WindowContainerToken,
+ ): Boolean =
+ hierarchyOps.any { hop ->
+ hop.isReparent &&
+ hop.container == task.asBinder() &&
+ hop.newParent == desk.minimizationRoot.token.asBinder()
+ }
+
+ private fun WindowContainerTransaction.hasUnminimizationHops(
+ desk: DeskRoots,
+ task: WindowContainerToken,
+ ): Boolean =
+ hierarchyOps.any { hop ->
+ hop.isReparent &&
+ hop.container == task.asBinder() &&
+ hop.newParent == desk.deskRoot.token.asBinder() &&
+ hop.toTop
+ }
+
private class FakeOnCreateCallback : DesksOrganizer.OnCreateCallback {
var deskId: Int? = null
val created: Boolean
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
index bc918450a3cf..714e5f486285 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
@@ -44,10 +44,12 @@ import androidx.test.filters.SmallTest;
import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.desktopmode.DesktopImmersiveController;
+import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.TransitionInfoBuilder;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.StubTransaction;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import org.junit.Before;
@@ -68,6 +70,7 @@ public class FreeformTaskTransitionObserverTest extends ShellTestCase {
@Mock private WindowDecorViewModel mWindowDecorViewModel;
@Mock private TaskChangeListener mTaskChangeListener;
@Mock private FocusTransitionObserver mFocusTransitionObserver;
+ @Mock private DesksTransitionObserver mDesksTransitionObserver;
private FreeformTaskTransitionObserver mTransitionObserver;
@@ -88,7 +91,8 @@ public class FreeformTaskTransitionObserverTest extends ShellTestCase {
Optional.of(mDesktopImmersiveController),
mWindowDecorViewModel,
Optional.of(mTaskChangeListener),
- mFocusTransitionObserver);
+ mFocusTransitionObserver,
+ Optional.of(mDesksTransitionObserver));
final ArgumentCaptor<Runnable> initRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
verify(mShellInit).addInitCallback(initRunnableCaptor.capture(), same(mTransitionObserver));
@@ -357,6 +361,18 @@ public class FreeformTaskTransitionObserverTest extends ShellTestCase {
verify(mDesktopImmersiveController).onTransitionFinished(transition, /* aborted= */ false);
}
+ @Test
+ public void onTransitionReady_forwardsToDesksTransitionObserver() {
+ final IBinder transition = mock(IBinder.class);
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, /* flags= */ 0)
+ .build();
+
+ mTransitionObserver.onTransitionReady(transition, info, new StubTransaction(),
+ new StubTransaction());
+
+ verify(mDesksTransitionObserver).onTransitionReady(transition, info);
+ }
+
private static TransitionInfo.Change createChange(int mode, int taskId, int windowingMode) {
final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = taskId;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
index 333569a7206e..5029371c3419 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
@@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.kotlin.MatchersKt.eq;
import static org.mockito.kotlin.VerificationKt.clearInvocations;
@@ -35,7 +36,9 @@ import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.RemoteAction;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -48,8 +51,10 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip2.animation.PipResizeAnimator;
import org.junit.Before;
@@ -107,6 +112,16 @@ public class PipTaskListenerTest {
}
@Test
+ public void constructor_addOnPipComponentChangedListener() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+
+ verify(mMockPipBoundsState).addOnPipComponentChangedListener(
+ any(PipBoundsState.OnPipComponentChangedListener.class));
+ }
+
+ @Test
public void setPictureInPictureParams_updatePictureInPictureParams() {
mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
@@ -359,6 +374,26 @@ public class PipTaskListenerTest {
verify(mMockPipResizeAnimator, times(0)).start();
}
+ @Test
+ public void onPipComponentChanged_clearPictureInPictureParams() {
+ when(mMockContext.getResources()).thenReturn(mock(Resources.class));
+ PipBoundsState pipBoundsState = new PipBoundsState(mMockContext,
+ mock(PhoneSizeSpecSource.class), mock(PipDisplayLayoutState.class));
+ pipBoundsState.setLastPipComponentName(new ComponentName("org.test", "test1"));
+
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, pipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Rational aspectRatio = new Rational(4, 3);
+ String action1 = "action1";
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ pipBoundsState.setLastPipComponentName(new ComponentName("org.test", "test2"));
+
+ assertTrue(mPipTaskListener.getPictureInPictureParams().empty());
+ }
+
private PictureInPictureParams getPictureInPictureParams(Rational aspectRatio,
String... actions) {
final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index e5a6a6d258dd..70603fad37b9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -27,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
@@ -213,7 +214,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(testRemote, "Test"), mStageCoordinator,
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, SNAP_TO_2_50_50);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -239,7 +240,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(testRemote, "Test"), mStageCoordinator,
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, SNAP_TO_2_50_50);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
@@ -262,7 +263,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(testRemote, "Test"), mStageCoordinator,
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, SNAP_TO_2_50_50);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
@@ -524,7 +525,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(new TestRemoteTransition(), "Test"),
- mStageCoordinator, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ mStageCoordinator, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false, SNAP_TO_2_50_50);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
mStageCoordinator.startAnimation(enterTransit, enterInfo,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index e9c4c31729e9..e246329446dc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -475,7 +475,7 @@ public class StageCoordinatorTests extends ShellTestCase {
mStageCoordinator.startTask(mTaskId, SPLIT_POSITION_TOP_OR_LEFT, null /*options*/,
null, SPLIT_INDEX_UNDEFINED);
verify(mSplitScreenTransitions).startEnterTransition(anyInt(),
- mWctCaptor.capture(), any(), any(), anyInt(), anyBoolean());
+ mWctCaptor.capture(), any(), any(), anyInt(), anyBoolean(), anyInt());
int windowingMode = mWctCaptor.getValue().getChanges().get(mBinder).getWindowingMode();
assertEquals(windowingMode, WINDOWING_MODE_UNDEFINED);
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 30594dcfa939..0d45149267cf 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1265,6 +1265,9 @@ struct ResTable_config
// Varies in length from 3 to 8 chars. Zero-filled value.
char localeNumberingSystem[8];
+ // Mark all padding explicitly so it's clear how much we can expand it.
+ char endPadding[3];
+
void copyFromDeviceNoSwap(const ResTable_config& o) {
const auto o_size = dtohl(o.size);
if (o_size >= sizeof(ResTable_config)) [[likely]] {
@@ -1422,6 +1425,13 @@ struct ResTable_config
void swapHtoD_slow();
};
+// Fix the struct size for backward compatibility
+static_assert(sizeof(ResTable_config) == 64);
+
+// Make sure there's no unaccounted padding in the structure.
+static_assert(offsetof(ResTable_config, endPadding) +
+ sizeof(ResTable_config::endPadding) == sizeof(ResTable_config));
+
/**
* A specification of the resources defined by a particular type.
*
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index a210ddf54b2e..7d227f793817 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -722,10 +722,15 @@ void RecyclingClippingPixelAllocator::copyIfNecessary() {
auto canvas = SkCanvas(recycledPixels->getSkBitmap());
SkRect destination = SkRect::Make(recycledPixels->info().bounds());
- destination.intersect(SkRect::Make(mSkiaBitmap->info().bounds()));
- canvas.drawImageRect(mSkiaBitmap->asImage(), *mDesiredSubset, destination,
- SkSamplingOptions(SkFilterMode::kLinear), nullptr,
- SkCanvas::kFast_SrcRectConstraint);
+ if (destination.intersect(SkRect::Make(mSkiaBitmap->info().bounds()))) {
+ canvas.drawImageRect(mSkiaBitmap->asImage(), *mDesiredSubset, destination,
+ SkSamplingOptions(SkFilterMode::kLinear), nullptr,
+ SkCanvas::kFast_SrcRectConstraint);
+ } else {
+ // The canvas would have discarded the draw operation automatically, but
+ // this case should have been detected before getting to this point.
+ ALOGE("Copy destination does not intersect image bounds");
+ }
} else {
void* dst = recycledPixels->pixels();
const size_t dstRowBytes = mRecycledBitmap->rowBytes();
diff --git a/media/java/Android.bp b/media/java/Android.bp
index 6878f9d61f6d..28b9d3bbc167 100644
--- a/media/java/Android.bp
+++ b/media/java/Android.bp
@@ -15,6 +15,7 @@ filegroup {
],
exclude_srcs: [
":framework-media-tv-tunerresourcemanager-sources-aidl",
+ ":framework-media-quality-sources-aidl",
],
visibility: [
"//frameworks/base",
diff --git a/media/java/android/media/quality/Android.bp b/media/java/android/media/quality/Android.bp
new file mode 100644
index 000000000000..080d5266ccb7
--- /dev/null
+++ b/media/java/android/media/quality/Android.bp
@@ -0,0 +1,39 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "framework-media-quality-sources-aidl",
+ srcs: [
+ "aidl/android/media/quality/*.aidl",
+ ],
+ path: "aidl",
+}
+
+aidl_interface {
+ name: "media_quality_aidl_interface",
+ unstable: true,
+ local_include_dir: "aidl",
+ backend: {
+ java: {
+ enabled: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
+ },
+ srcs: [
+ ":framework-media-quality-sources-aidl",
+ ],
+}
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 0d6d32a22dae..bfd01380a2ee 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -274,9 +274,9 @@ public final class MediaQualityManager {
@NonNull String name,
@Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
- return mService.getPictureProfile(type, name, optionsBundle, mUserHandle);
+ boolean includeParams = options == null || options.mParametersIncluded;
+ return mService.getPictureProfile(
+ type, name, includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -299,10 +299,9 @@ public final class MediaQualityManager {
public List<PictureProfile> getPictureProfilesByPackage(
@NonNull String packageName, @Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
+ boolean includeParams = options == null || options.mParametersIncluded;
return mService.getPictureProfilesByPackage(
- packageName, optionsBundle, mUserHandle);
+ packageName, includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -321,9 +320,8 @@ public final class MediaQualityManager {
@NonNull
public List<PictureProfile> getAvailablePictureProfiles(@Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
- return mService.getAvailablePictureProfiles(optionsBundle, mUserHandle);
+ boolean includeParams = options == null || options.mParametersIncluded;
+ return mService.getAvailablePictureProfiles(includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -344,7 +342,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public boolean setDefaultPictureProfile(@Nullable String pictureProfileId) {
try {
- return mService.setDefaultPictureProfile(pictureProfileId, mUserHandle);
+ return mService.setDefaultPictureProfile(pictureProfileId, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -361,7 +359,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<String> getPictureProfilePackageNames() {
try {
- return mService.getPictureProfilePackageNames(mUserHandle);
+ return mService.getPictureProfilePackageNames(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -373,7 +371,7 @@ public final class MediaQualityManager {
*/
public List<PictureProfileHandle> getPictureProfileHandle(String[] id) {
try {
- return mService.getPictureProfileHandle(id, mUserHandle);
+ return mService.getPictureProfileHandle(id, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -385,7 +383,7 @@ public final class MediaQualityManager {
*/
public List<SoundProfileHandle> getSoundProfileHandle(String[] id) {
try {
- return mService.getSoundProfileHandle(id, mUserHandle);
+ return mService.getSoundProfileHandle(id, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -401,7 +399,7 @@ public final class MediaQualityManager {
*/
public void createPictureProfile(@NonNull PictureProfile pp) {
try {
- mService.createPictureProfile(pp, mUserHandle);
+ mService.createPictureProfile(pp, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -416,7 +414,7 @@ public final class MediaQualityManager {
*/
public void updatePictureProfile(@NonNull String profileId, @NonNull PictureProfile pp) {
try {
- mService.updatePictureProfile(profileId, pp, mUserHandle);
+ mService.updatePictureProfile(profileId, pp, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -430,7 +428,7 @@ public final class MediaQualityManager {
*/
public void removePictureProfile(@NonNull String profileId) {
try {
- mService.removePictureProfile(profileId, mUserHandle);
+ mService.removePictureProfile(profileId, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -484,9 +482,8 @@ public final class MediaQualityManager {
@NonNull String name,
@Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
- return mService.getSoundProfile(type, name, optionsBundle, mUserHandle);
+ boolean includeParams = options == null || options.mParametersIncluded;
+ return mService.getSoundProfile(type, name, includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -510,9 +507,9 @@ public final class MediaQualityManager {
public List<SoundProfile> getSoundProfilesByPackage(
@NonNull String packageName, @Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
- return mService.getSoundProfilesByPackage(packageName, optionsBundle, mUserHandle);
+ boolean includeParams = options == null || options.mParametersIncluded;
+ return mService.getSoundProfilesByPackage(
+ packageName, includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -531,9 +528,8 @@ public final class MediaQualityManager {
@NonNull
public List<SoundProfile> getAvailableSoundProfiles(@Nullable ProfileQueryParams options) {
try {
- Bundle optionsBundle = options == null
- ? ProfileQueryParams.DEFAULT.toBundle() : options.toBundle();
- return mService.getAvailableSoundProfiles(optionsBundle, mUserHandle);
+ boolean includeParams = options == null || options.mParametersIncluded;
+ return mService.getAvailableSoundProfiles(includeParams, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -554,7 +550,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public boolean setDefaultSoundProfile(@Nullable String soundProfileId) {
try {
- return mService.setDefaultSoundProfile(soundProfileId, mUserHandle);
+ return mService.setDefaultSoundProfile(soundProfileId, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -572,7 +568,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<String> getSoundProfilePackageNames() {
try {
- return mService.getSoundProfilePackageNames(mUserHandle);
+ return mService.getSoundProfilePackageNames(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -589,7 +585,7 @@ public final class MediaQualityManager {
*/
public void createSoundProfile(@NonNull SoundProfile sp) {
try {
- mService.createSoundProfile(sp, mUserHandle);
+ mService.createSoundProfile(sp, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -604,7 +600,7 @@ public final class MediaQualityManager {
*/
public void updateSoundProfile(@NonNull String profileId, @NonNull SoundProfile sp) {
try {
- mService.updateSoundProfile(profileId, sp, mUserHandle);
+ mService.updateSoundProfile(profileId, sp, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -618,7 +614,7 @@ public final class MediaQualityManager {
*/
public void removeSoundProfile(@NonNull String profileId) {
try {
- mService.removeSoundProfile(profileId, mUserHandle);
+ mService.removeSoundProfile(profileId, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -636,7 +632,7 @@ public final class MediaQualityManager {
@NonNull
public List<ParameterCapability> getParameterCapabilities(@NonNull List<String> names) {
try {
- return mService.getParameterCapabilities(names, mUserHandle);
+ return mService.getParameterCapabilities(names, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -654,7 +650,7 @@ public final class MediaQualityManager {
@NonNull
public List<String> getPictureProfileAllowList() {
try {
- return mService.getPictureProfileAllowList(mUserHandle);
+ return mService.getPictureProfileAllowList(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -668,7 +664,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setPictureProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setPictureProfileAllowList(packageNames, mUserHandle);
+ mService.setPictureProfileAllowList(packageNames, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -686,7 +682,7 @@ public final class MediaQualityManager {
@NonNull
public List<String> getSoundProfileAllowList() {
try {
- return mService.getSoundProfileAllowList(mUserHandle);
+ return mService.getSoundProfileAllowList(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -700,7 +696,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setSoundProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setSoundProfileAllowList(packageNames, mUserHandle);
+ mService.setSoundProfileAllowList(packageNames, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -712,7 +708,7 @@ public final class MediaQualityManager {
*/
public boolean isSupported() {
try {
- return mService.isSupported(mUserHandle);
+ return mService.isSupported(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -730,7 +726,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setAutoPictureQualityEnabled(boolean enabled) {
try {
- mService.setAutoPictureQualityEnabled(enabled, mUserHandle);
+ mService.setAutoPictureQualityEnabled(enabled, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -741,7 +737,7 @@ public final class MediaQualityManager {
*/
public boolean isAutoPictureQualityEnabled() {
try {
- return mService.isAutoPictureQualityEnabled(mUserHandle);
+ return mService.isAutoPictureQualityEnabled(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -758,7 +754,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setSuperResolutionEnabled(boolean enabled) {
try {
- mService.setSuperResolutionEnabled(enabled, mUserHandle);
+ mService.setSuperResolutionEnabled(enabled, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -769,7 +765,7 @@ public final class MediaQualityManager {
*/
public boolean isSuperResolutionEnabled() {
try {
- return mService.isSuperResolutionEnabled(mUserHandle);
+ return mService.isSuperResolutionEnabled(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -787,7 +783,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setAutoSoundQualityEnabled(boolean enabled) {
try {
- mService.setAutoSoundQualityEnabled(enabled, mUserHandle);
+ mService.setAutoSoundQualityEnabled(enabled, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -798,7 +794,7 @@ public final class MediaQualityManager {
*/
public boolean isAutoSoundQualityEnabled() {
try {
- return mService.isAutoSoundQualityEnabled(mUserHandle);
+ return mService.isAutoSoundQualityEnabled(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -847,7 +843,7 @@ public final class MediaQualityManager {
@NonNull AmbientBacklightSettings settings) {
Preconditions.checkNotNull(settings);
try {
- mService.setAmbientBacklightSettings(settings, mUserHandle);
+ mService.setAmbientBacklightSettings(settings, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -858,7 +854,7 @@ public final class MediaQualityManager {
*/
public boolean isAmbientBacklightEnabled() {
try {
- return mService.isAmbientBacklightEnabled(mUserHandle);
+ return mService.isAmbientBacklightEnabled(mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -872,7 +868,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.READ_COLOR_ZONES)
public void setAmbientBacklightEnabled(boolean enabled) {
try {
- mService.setAmbientBacklightEnabled(enabled, mUserHandle);
+ mService.setAmbientBacklightEnabled(enabled, mUserHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/quality/SoundProfileHandle.java b/media/java/android/media/quality/SoundProfileHandle.java
deleted file mode 100644
index edb546efdaf3..000000000000
--- a/media/java/android/media/quality/SoundProfileHandle.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.quality;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A type-safe handle to a sound profile.
- *
- * @hide
- */
-public final class SoundProfileHandle implements Parcelable {
- public static final @NonNull SoundProfileHandle NONE = new SoundProfileHandle(-1000);
-
- private final long mId;
-
- /** @hide */
- public SoundProfileHandle(long id) {
- mId = id;
- }
-
- /** @hide */
- public long getId() {
- return mId;
- }
-
- /** @hide */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeLong(mId);
- }
-
- /** @hide */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** @hide */
- public static final @NonNull Creator<SoundProfileHandle> CREATOR =
- new Creator<SoundProfileHandle>() {
- @Override
- public SoundProfileHandle createFromParcel(Parcel in) {
- return new SoundProfileHandle(in);
- }
-
- @Override
- public SoundProfileHandle[] newArray(int size) {
- return new SoundProfileHandle[size];
- }
- };
-
- private SoundProfileHandle(@NonNull Parcel in) {
- mId = in.readLong();
- }
-}
diff --git a/media/java/android/media/quality/ActiveProcessingPicture.aidl b/media/java/android/media/quality/aidl/android/media/quality/ActiveProcessingPicture.aidl
index 2851306f6e4d..2851306f6e4d 100644
--- a/media/java/android/media/quality/ActiveProcessingPicture.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/ActiveProcessingPicture.aidl
diff --git a/media/java/android/media/quality/AmbientBacklightEvent.aidl b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightEvent.aidl
index 174cd461e846..174cd461e846 100644
--- a/media/java/android/media/quality/AmbientBacklightEvent.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightEvent.aidl
diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.aidl b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightMetadata.aidl
index b95a474fbf90..b95a474fbf90 100644
--- a/media/java/android/media/quality/AmbientBacklightMetadata.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightMetadata.aidl
diff --git a/media/java/android/media/quality/AmbientBacklightSettings.aidl b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightSettings.aidl
index e2cdd03194cd..e2cdd03194cd 100644
--- a/media/java/android/media/quality/AmbientBacklightSettings.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/AmbientBacklightSettings.aidl
diff --git a/media/java/android/media/quality/IAmbientBacklightCallback.aidl b/media/java/android/media/quality/aidl/android/media/quality/IAmbientBacklightCallback.aidl
index 159f5b7b5e71..159f5b7b5e71 100644
--- a/media/java/android/media/quality/IAmbientBacklightCallback.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/IAmbientBacklightCallback.aidl
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl
index 6e9fa1dcf93d..0191ea786de0 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl
@@ -25,57 +25,57 @@ import android.media.quality.PictureProfileHandle;
import android.media.quality.PictureProfile;
import android.media.quality.SoundProfileHandle;
import android.media.quality.SoundProfile;
-import android.os.Bundle;
-import android.os.UserHandle;
/**
* Interface for Media Quality Manager
* @hide
*/
interface IMediaQualityManager {
- PictureProfile createPictureProfile(in PictureProfile pp, in UserHandle user);
- void updatePictureProfile(in String id, in PictureProfile pp, in UserHandle user);
- void removePictureProfile(in String id, in UserHandle user);
- boolean setDefaultPictureProfile(in String id, in UserHandle user);
+ // TODO: use UserHandle
+ PictureProfile createPictureProfile(in PictureProfile pp, int userId);
+ void updatePictureProfile(in String id, in PictureProfile pp, int userId);
+ void removePictureProfile(in String id, int userId);
+ boolean setDefaultPictureProfile(in String id, int userId);
+ // TODO: use Bundle for includeParams
PictureProfile getPictureProfile(
- in int type, in String name, in Bundle options, in UserHandle user);
+ in int type, in String name, in boolean includeParams, int userId);
List<PictureProfile> getPictureProfilesByPackage(
- in String packageName, in Bundle options, in UserHandle user);
- List<PictureProfile> getAvailablePictureProfiles(in Bundle options, in UserHandle user);
- List<String> getPictureProfilePackageNames(in UserHandle user);
- List<String> getPictureProfileAllowList(in UserHandle user);
- void setPictureProfileAllowList(in List<String> packages, in UserHandle user);
- List<PictureProfileHandle> getPictureProfileHandle(in String[] id, in UserHandle user);
+ in String packageName, in boolean includeParams, int userId);
+ List<PictureProfile> getAvailablePictureProfiles(in boolean includeParams, int userId);
+ List<String> getPictureProfilePackageNames(int userId);
+ List<String> getPictureProfileAllowList(int userId);
+ void setPictureProfileAllowList(in List<String> packages, int userId);
+ List<PictureProfileHandle> getPictureProfileHandle(in String[] id, int userId);
- SoundProfile createSoundProfile(in SoundProfile pp, in UserHandle user);
- void updateSoundProfile(in String id, in SoundProfile pp, in UserHandle user);
- void removeSoundProfile(in String id, in UserHandle user);
- boolean setDefaultSoundProfile(in String id, in UserHandle user);
+ SoundProfile createSoundProfile(in SoundProfile pp, int userId);
+ void updateSoundProfile(in String id, in SoundProfile pp, int userId);
+ void removeSoundProfile(in String id, int userId);
+ boolean setDefaultSoundProfile(in String id, int userId);
SoundProfile getSoundProfile(
- in int type, in String name, in Bundle options, in UserHandle user);
+ in int type, in String name, in boolean includeParams, int userId);
List<SoundProfile> getSoundProfilesByPackage(
- in String packageName, in Bundle options, in UserHandle user);
- List<SoundProfile> getAvailableSoundProfiles(in Bundle options, in UserHandle user);
- List<String> getSoundProfilePackageNames(in UserHandle user);
- List<String> getSoundProfileAllowList(in UserHandle user);
- void setSoundProfileAllowList(in List<String> packages, in UserHandle user);
- List<SoundProfileHandle> getSoundProfileHandle(in String[] id, in UserHandle user);
+ in String packageName, in boolean includeParams, int userId);
+ List<SoundProfile> getAvailableSoundProfiles(in boolean includeParams, int userId);
+ List<String> getSoundProfilePackageNames(int userId);
+ List<String> getSoundProfileAllowList(int userId);
+ void setSoundProfileAllowList(in List<String> packages, int userId);
+ List<SoundProfileHandle> getSoundProfileHandle(in String[] id, int userId);
void registerPictureProfileCallback(in IPictureProfileCallback cb);
void registerSoundProfileCallback(in ISoundProfileCallback cb);
void registerAmbientBacklightCallback(in IAmbientBacklightCallback cb);
- List<ParameterCapability> getParameterCapabilities(in List<String> names, in UserHandle user);
+ List<ParameterCapability> getParameterCapabilities(in List<String> names, int userId);
- boolean isSupported(in UserHandle user);
- void setAutoPictureQualityEnabled(in boolean enabled, in UserHandle user);
- boolean isAutoPictureQualityEnabled(in UserHandle user);
- void setSuperResolutionEnabled(in boolean enabled, in UserHandle user);
- boolean isSuperResolutionEnabled(in UserHandle user);
- void setAutoSoundQualityEnabled(in boolean enabled, in UserHandle user);
- boolean isAutoSoundQualityEnabled(in UserHandle user);
+ boolean isSupported(int userId);
+ void setAutoPictureQualityEnabled(in boolean enabled, int userId);
+ boolean isAutoPictureQualityEnabled(int userId);
+ void setSuperResolutionEnabled(in boolean enabled, int userId);
+ boolean isSuperResolutionEnabled(int userId);
+ void setAutoSoundQualityEnabled(in boolean enabled, int userId);
+ boolean isAutoSoundQualityEnabled(int userId);
- void setAmbientBacklightSettings(in AmbientBacklightSettings settings, in UserHandle user);
- void setAmbientBacklightEnabled(in boolean enabled, in UserHandle user);
- boolean isAmbientBacklightEnabled(in UserHandle user);
+ void setAmbientBacklightSettings(in AmbientBacklightSettings settings, int userId);
+ void setAmbientBacklightEnabled(in boolean enabled, int userId);
+ boolean isAmbientBacklightEnabled(int userId);
}
diff --git a/media/java/android/media/quality/IPictureProfileCallback.aidl b/media/java/android/media/quality/aidl/android/media/quality/IPictureProfileCallback.aidl
index eed77f695416..eed77f695416 100644
--- a/media/java/android/media/quality/IPictureProfileCallback.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/IPictureProfileCallback.aidl
diff --git a/media/java/android/media/quality/ISoundProfileCallback.aidl b/media/java/android/media/quality/aidl/android/media/quality/ISoundProfileCallback.aidl
index 3871fb212259..3871fb212259 100644
--- a/media/java/android/media/quality/ISoundProfileCallback.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/ISoundProfileCallback.aidl
diff --git a/media/java/android/media/quality/ParameterCapability.aidl b/media/java/android/media/quality/aidl/android/media/quality/ParameterCapability.aidl
index eb2ac97916f3..eb2ac97916f3 100644
--- a/media/java/android/media/quality/ParameterCapability.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/ParameterCapability.aidl
diff --git a/media/java/android/media/quality/PictureProfile.aidl b/media/java/android/media/quality/aidl/android/media/quality/PictureProfile.aidl
index 41d018b12f33..41d018b12f33 100644
--- a/media/java/android/media/quality/PictureProfile.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/PictureProfile.aidl
diff --git a/media/java/android/media/quality/PictureProfileHandle.aidl b/media/java/android/media/quality/aidl/android/media/quality/PictureProfileHandle.aidl
index 5d14631dbb73..5d14631dbb73 100644
--- a/media/java/android/media/quality/PictureProfileHandle.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/PictureProfileHandle.aidl
diff --git a/media/java/android/media/quality/SoundProfile.aidl b/media/java/android/media/quality/aidl/android/media/quality/SoundProfile.aidl
index e79fcaac97be..e79fcaac97be 100644
--- a/media/java/android/media/quality/SoundProfile.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/SoundProfile.aidl
diff --git a/media/java/android/media/quality/SoundProfileHandle.aidl b/media/java/android/media/quality/aidl/android/media/quality/SoundProfileHandle.aidl
index 6b8161c8cc43..ea26b19d84d7 100644
--- a/media/java/android/media/quality/SoundProfileHandle.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/SoundProfileHandle.aidl
@@ -16,4 +16,7 @@
package android.media.quality;
-parcelable SoundProfileHandle;
+// TODO: add SoundProfileHandle.java
+parcelable SoundProfileHandle {
+ long id;
+}
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index b802d0f69a08..8e5a2b7c3663 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Kanselleer"</string>
<string name="consent_back" msgid="2560683030046918882">"Terug"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Rollees met die lys af"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Afwaartse pyl"</string>
<string name="permission_expand" msgid="893185038020887411">"Vou <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> uit"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Vou <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> in"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Gee programme op &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dieselfde toestemmings as op &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index d4d0b0708302..40472d253072 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ይቅር"</string>
<string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"በዝርዝሩ ላይ ወደታች ያሸብልሉ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"የአውርድ ቀስት"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ን ዘርጋ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ን ሰብስብ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"በ&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ላይ ላሉ መተግበሪያዎች በ&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ላይ ካሉት ጋር ተመሳሳይ ፈቃዶች ይሰጣቸው?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 322d422f60d7..1f3ee732c8ce 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
<string name="consent_cancel" msgid="5655005528379285841">"বাতিল কৰক"</string>
<string name="consent_back" msgid="2560683030046918882">"উভতি যাওক"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"সূচীখনত তললৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"তলমুৱা কাঁড়"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> বিস্তাৰ কৰক"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> সংকোচন কৰক"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"এপ্‌সমূহক &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ত দিয়াৰ দৰে &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;তো একে অনুমতি প্ৰদান কৰিবনে?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 9f3ab2bd50cd..aa4788ac7e1e 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Ləğv edin"</string>
<string name="consent_back" msgid="2560683030046918882">"Geriyə"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Siyahını aşağı sürüşdürün"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Aşağı ox"</string>
<string name="permission_expand" msgid="893185038020887411">"Genişləndirin: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Yığcamlaşdırın: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazındakı tətbiqlərə &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazındakılarla eyni icazələr verilsin?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index d28b9b26fb07..3dcb585a0bc2 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Otkaži"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Skrolujte nadole na listi"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Strelica nadole"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skupi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Aplikcijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dajete sve dozvole kao na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 214dc71a6a88..f5cf720a64a5 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
<string name="consent_cancel" msgid="5655005528379285841">"বাতিল করুন"</string>
<string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"তালিকা নিচের দিকে স্ক্রল করুন"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"নিম্নমুখী তীরচিহ্ন"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> বড় করুন"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> আড়াল করুন"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-এ যে অনুমতি দেওয়া আছে &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-এও সেই একই অনুমতি দিতে চান?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index b23f600cbcf0..a87ea18f831c 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Otkaži"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Klizanje nadolje na listi"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Strelica nadolje"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširivanje stavke <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sužavanje stavke <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dati aplikacijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ista odobrenja kao na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 21f3871d8209..7ec2b8b0dab6 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancel·la"</string>
<string name="consent_back" msgid="2560683030046918882">"Enrere"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Desplaça la llista cap avall"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Fletxa avall"</string>
<string name="permission_expand" msgid="893185038020887411">"Desplega <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Replega <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vols concedir a les aplicacions del dispositiu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; els mateixos permisos que tenen a &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index cd8913012eeb..a1ea39b26eeb 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Zrušit"</string>
<string name="consent_back" msgid="2560683030046918882">"Zpět"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Přejít v seznamu dolů"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Šipka dolů"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozbalit sekci <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sbalit sekci <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Udělit aplikacím v zařízení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; stejné oprávnění, jako mají v zařízení &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 6dc34e77c5ce..97e6fe563dd6 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Annuller"</string>
<string name="consent_back" msgid="2560683030046918882">"Tilbage"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Rul ned på listen"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Pil ned"</string>
<string name="permission_expand" msgid="893185038020887411">"Udvid <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skjul <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vil du give apps på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; de samme tilladelser som på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 4dc292916628..fc0231f24445 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Abbrechen"</string>
<string name="consent_back" msgid="2560683030046918882">"Zurück"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"In der Liste nach unten scrollen"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Abwärtspfeil"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> maximieren"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> minimieren"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Apps auf &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; die gleichen Berechtigungen geben wie auf &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index bbd81bf68b9d..68c74e0e82f8 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scroll down the list"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Downward arrow"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index bbd81bf68b9d..68c74e0e82f8 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scroll down the list"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Downward arrow"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index bbd81bf68b9d..68c74e0e82f8 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scroll down the list"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Downward arrow"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index f8e2c742cccc..d74b4f822c15 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Desplazarse hacia abajo por la lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Flecha hacia abajo"</string>
<string name="permission_expand" msgid="893185038020887411">"Desplegar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"¿Dar a las aplicaciones de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; los mismos permisos que &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index fb36c46d2d6a..cf4fe25ab0d0 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"اجازه ندادن"</string>
<string name="consent_cancel" msgid="5655005528379285841">"لغو"</string>
<string name="consent_back" msgid="2560683030046918882">"برگشتن"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"پیمایش به‌پایین فهرست"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"جهت‌نمای پایین"</string>
<string name="permission_expand" msgid="893185038020887411">"ازهم بازکردن <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"جمع کردن <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏به برنامه‌های موجود در &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; همان اجازه‌های &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; داده شود؟"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index ff6cae1bbe3c..4be6a5acbf34 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Peruuta"</string>
<string name="consent_back" msgid="2560683030046918882">"Takaisin"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Vieritä listaa alaspäin"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Alanuoli"</string>
<string name="permission_expand" msgid="893185038020887411">"Laajenna <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Tiivistä <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Anna laitteen &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; sovelluksille samat luvat kuin laitteella &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 4d7de76334de..70beafba782c 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Annuler"</string>
<string name="consent_back" msgid="2560683030046918882">"Retour"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Faire défiler la liste en bas"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Flèche vers le bas"</string>
<string name="permission_expand" msgid="893185038020887411">"Développer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Réduire <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder aux applis sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; les autorisations déjà accordées sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index d4c12fba1492..394efae9da0e 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Annuler"</string>
<string name="consent_back" msgid="2560683030046918882">"Retour"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Faire défiler la liste vers le bas"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Flèche vers le bas"</string>
<string name="permission_expand" msgid="893185038020887411">"Développer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Réduire <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder les mêmes autorisations aux applis sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; que sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 999ab9741084..ce23be8e8fbb 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Desprazarse abaixo na lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Frecha cara abaixo"</string>
<string name="permission_expand" msgid="893185038020887411">"Despregar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Queres darlles ás aplicacións de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; os mesmos permisos que teñen as de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 51d07c97fa5c..7956ba6814ff 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
<string name="consent_cancel" msgid="5655005528379285841">"રદ કરો"</string>
<string name="consent_back" msgid="2560683030046918882">"પાછળ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"સૂચિ પર નીચે સ્ક્રોલ કરો"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"નીચેની તરફ ઍરો"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ને મોટું કરો"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ને નાનું કરો"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; પરની ઍપને &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; પર છે તે જ પરવાનગીઓ આપીએ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 04872e53cb36..326564e90f5e 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Odustani"</string>
<string name="consent_back" msgid="2560683030046918882">"Natrag"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Pomicanje po popisu"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Strelica prema dolje"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sažmi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dati jednaka dopuštenja aplikacijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; kao i na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index e7c71391fb91..cbf1d8d7f921 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Չեղարկել"</string>
<string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Թերթեք ներքև"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Ներքև սլաք"</string>
<string name="permission_expand" msgid="893185038020887411">"Ծավալել «<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>» բաժինը"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ծալել «<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>» բաժինը"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-ում հավելվածներին տա՞լ նույն թույլտվությունները, ինչ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-ում"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index f58220563e4e..fe3406ecd6be 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Batal"</string>
<string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scroll daftar ke bawah"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Panah bawah"</string>
<string name="permission_expand" msgid="893185038020887411">"Luaskan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ciutkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Berikan aplikasi di &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; izin yang sama seperti di &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index b66133cddeb6..9e366d6ec3a9 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Hætta við"</string>
<string name="consent_back" msgid="2560683030046918882">"Til baka"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Fletta niður listann"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Ör niður"</string>
<string name="permission_expand" msgid="893185038020887411">"Stækka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Minnka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Veita forritum í &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; sömu heimildir og í &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 626ae7a3b50e..1e299b72ffb6 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ביטול"</string>
<string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"גלילה למטה ברשימה"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"חץ למטה"</string>
<string name="permission_expand" msgid="893185038020887411">"הרחבה של <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"כיווץ של <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏האם לתת לאפליקציות ב-‎&lt;strong&gt;‎‏<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>‏‎&lt;/strong&gt;‎‏ את אותן הרשאות כמו ב-‏‎&lt;strong&gt;‎‏<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>‏‎&lt;/strong&gt;‎‏?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 97f3087663cf..d0214aeb13ca 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
<string name="consent_cancel" msgid="5655005528379285841">"გაუქმება"</string>
<string name="consent_back" msgid="2560683030046918882">"უკან"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"გადაადგილება სიის ქვემოთ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ქვემოთ მიმართული ისარი"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-ის გაფართოება"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-ის ჩაკეცვა"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"გსურთ აპებს &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-ზე იგივე ნებართვები მიანიჭოთ, როგორიც აქვს &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-ზე?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 4d77c6cc588c..e7944154b516 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Бас тарту"</string>
<string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Тізім соңына дейін айналдыру"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Төмен бағытталған перне"</string>
<string name="permission_expand" msgid="893185038020887411">"\"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\" панелін жаю"</string>
<string name="permission_collapse" msgid="3320833884220844084">"\"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\" панелін жию"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; құрылғысындағы қолданбаларға &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысындағыдай рұқсаттар берілсін бе?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 751ac1f1a5ad..a957f48f1a13 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ರದ್ದುಮಾಡಿ"</string>
<string name="consent_back" msgid="2560683030046918882">"ಹಿಂದೆ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ಪಟ್ಟಿಯನ್ನು ಕೆಳಗೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ಕೆಳಮುಖ ಬಾಣ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ಅನ್ನು ವಿಸ್ತರಿಸಿ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ಅನ್ನು ಕುಗ್ಗಿಸಿ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;/strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿನ ಅನುಮತಿಗಳನ್ನೇ &lt;/strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿನ ಆ್ಯಪ್‌ಗಳಿಗೆ ನೀಡಬೇಕೆ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index a7a5dc1bd204..d7d489af9755 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
<string name="consent_cancel" msgid="5655005528379285841">"취소"</string>
<string name="consent_back" msgid="2560683030046918882">"뒤로"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"목록을 아래로 스크롤"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"아래쪽 화살표"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> 펼치기"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> 접기"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;에 설치된 앱에 &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;에 설치된 앱과 동일한 권한을 부여하시겠습니까?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 991fc9f13248..3f8c58af129a 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Жок"</string>
<string name="consent_back" msgid="2560683030046918882">"Артка"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Тизменин ылдый жагына сыдыруу"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Ылдый караган жебе"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жайып көрсөтүү"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жыйыштыруу"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; түзмөгүнө да &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүнө берилген уруксаттар берилсинби?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 91399b60f7b7..457efdb6f864 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ຍົກເລີກ"</string>
<string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ເລື່ອນລາຍຊື່ລົງ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ລູກສອນຊີ້ລົງ"</string>
<string name="permission_expand" msgid="893185038020887411">"ຂະຫຍາຍ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"ຫຍໍ້ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ລົງ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ໃຫ້ການອະນຸຍາດແອັບຢູ່ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ເປັນການອະນຸຍາດດຽວກັນກັບຢູ່ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ບໍ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 35c748125180..01c9ed5e4657 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Atcelt"</string>
<string name="consent_back" msgid="2560683030046918882">"Atpakaļ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Ritināt sarakstu lejup"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Lejupvērsta bultiņa"</string>
<string name="permission_expand" msgid="893185038020887411">"Izvērst: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sakļaut: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vai lietotnēm ierīcē &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; piešķirt tādas pašas atļaujas kā ierīcē &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 1eaf2d23690b..d9c8695d7c13 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Откажи"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Лизгај надолу по списокот"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрелка надолу"</string>
<string name="permission_expand" msgid="893185038020887411">"Прошири <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Собери <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Дасе дадат исти дозволи на апликациите на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; како на &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 52fcb1f9a7b6..828b6cfac332 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
<string name="consent_cancel" msgid="5655005528379285841">"റദ്ദാക്കുക"</string>
<string name="consent_back" msgid="2560683030046918882">"മടങ്ങുക"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ലിസ്റ്റ് താഴേക്ക് സ്ക്രോൾ ചെയ്യൂ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"താഴേക്കുള്ള അമ്പടയാളം"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> വികസിപ്പിക്കുക"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ചുരുക്കുക"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; എന്നതിലെ അതേ അനുമതികൾ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിലെ ആപ്പുകൾക്ക് നൽകണോ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 5faf241c81a1..be6eb8e6fe58 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Цуцлах"</string>
<string name="consent_back" msgid="2560683030046918882">"Буцах"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Жагсаалтыг доош гүйлгэх"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Доош заасан сум"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-г дэлгэх"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-г хураах"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; дээрх аппуудад &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; дээрхтэй адил зөвшөөрөл өгөх үү?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 94e49fecd7e0..99f59a641b89 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
<string name="consent_cancel" msgid="5655005528379285841">"रद्द करा"</string>
<string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"सूचीवर खाली स्क्रोल करा"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"खालच्या दिशेचा अ‍ॅरो"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> चा विस्तार करा"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> कोलॅप्स करा"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; वरील अ‍ॅप्सना &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; प्रमाणेच परवानग्या द्यायच्या आहेत का?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 8b1170ba03d2..9c15c0607b7b 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Batal"</string>
<string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Tatal ke bawah senarai"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Anak panah ke bawah"</string>
<string name="permission_expand" msgid="893185038020887411">"Kembangkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Kuncupkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Beri apl pada &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; kebenaran yang sama seperti pada &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index faca3e35d549..6068c43b5274 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"မလုပ်တော့"</string>
<string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"စာရင်းအောက်သို့ လှိမ့်ရန်"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"အောက်ညွှန်မြား"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ကို ပိုပြရန်"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ကို လျှော့ပြရန်"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"အက်ပ်များကို &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; တွင်ပေးထားသည့် ခွင့်ပြုချက်များအတိုင်း &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; တွင် ပေးမလား။"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 4188951a15ed..eb5e2e996bdc 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Avbryt"</string>
<string name="consent_back" msgid="2560683030046918882">"Tilbake"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Rull nedover i listen"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Nedoverpil"</string>
<string name="permission_expand" msgid="893185038020887411">"Vis <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skjul <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vil du gi apper på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; de samme tillatelsene som på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 2cd4fef2c53a..f3b56de35f12 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
<string name="consent_cancel" msgid="5655005528379285841">"रद्द गर्नुहोस्"</string>
<string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"सूचीको तलतिर स्क्रोल गर्नुहोस्"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"डाउनवार्ड एरो"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> एक्स्पान्ड गर्नुहोस्"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> कोल्याप्स गर्नुहोस्"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; मा भएका एपहरूलाई पनि &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; मा दिइएकै अनुमति दिने हो?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 8298a5b9d411..bd602e496d74 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ତାଲିକା ତଳକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ଡାଉନୱାର୍ଡ ତୀର"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>କୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>କୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ପରି &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;ରେ ଥିବା ଆପ୍ସକୁ ସମାନ ଅନୁମତିଗୁଡ଼ିକ ଦେବେ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index fe13c00dfb98..ae0b59dbc21d 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ਰੱਦ ਕਰੋ"</string>
<string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ਸੂਚੀ ਨੂੰ ਹੇਠਾਂ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ਹੇਠਾਂ ਤੀਰ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ਨੂੰ ਸਮੇਟੋ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ਕੀ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਐਪਾਂ ਨੂੰ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਐਪਾਂ ਵਾਂਗ ਇਜਾਜ਼ਤਾਂ ਦੇਣੀਆਂ ਹਨ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 1599f3f333fe..bce0a6ebdaa5 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Anuluj"</string>
<string name="consent_back" msgid="2560683030046918882">"Wstecz"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Przewiń listę w dół"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Strzałka w dół"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozwiń sekcję <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Zwiń sekcję <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Czy aplikacjom na urządzeniu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; przyznać te same uprawnienia co na urządzeniu &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 85c23ea7f253..35b653a4e6de 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Role para baixo na lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Seta para baixo"</string>
<string name="permission_expand" msgid="893185038020887411">"Abrir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Fechar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar aos apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas permissões do dispositivo &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 85c23ea7f253..35b653a4e6de 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Role para baixo na lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Seta para baixo"</string>
<string name="permission_expand" msgid="893185038020887411">"Abrir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Fechar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar aos apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas permissões do dispositivo &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 6820d5b44633..0fdeb29f0400 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nu permite"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Anulează"</string>
<string name="consent_back" msgid="2560683030046918882">"Înapoi"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Derulează în jos lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Săgeată în jos"</string>
<string name="permission_expand" msgid="893185038020887411">"Extinde <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Restrânge <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Acorzi aplicațiilor de pe &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; aceleași permisiuni ca pe &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 3213a2faa7d8..872f45eae425 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Отмена"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Прокрутить список вниз"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрелка вниз"</string>
<string name="permission_expand" msgid="893185038020887411">"Разворачивать список \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\"."</string>
<string name="permission_collapse" msgid="3320833884220844084">"Сворачивать список \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\"."</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Предоставить приложениям на устройстве &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; те же разрешения, что на устройстве &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 7fd66110c10b..ec362f2c33f2 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
<string name="consent_cancel" msgid="5655005528379285841">"අවලංගු කරන්න"</string>
<string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"ලැයිස්තුව පහළට අනුචලනය කරන්න"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"පහළට ඊතලය"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> විදහන්න"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> හකුළන්න"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the හි යෙදුම්වලට &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; හි අවසරම දෙන්නද?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 5194f215444a..cbf56486a044 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Zrušiť"</string>
<string name="consent_back" msgid="2560683030046918882">"Späť"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Posunúť zoznam nadol"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Šípka nadol"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozbaliť sekciu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Zbaliť sekciu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Chcete udeliť aplikáciám v zariadení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; rovnaké povolenia ako v zariadení &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 220022095677..20570c300038 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Prekliči"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazaj"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Pomikanje navzdol po seznamu"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Puščica navzdol"</string>
<string name="permission_expand" msgid="893185038020887411">"Razširi dovoljenje »<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>«"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Strni dovoljenje »<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>«"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ali želite aplikacijam v napravi &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; odobriti enaka dovoljenja kot v napravi &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index f683dd9e2974..32ede4022156 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Anulo"</string>
<string name="consent_back" msgid="2560683030046918882">"Pas"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Lëviz poshtë në listë"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Shigjeta poshtë"</string>
<string name="permission_expand" msgid="893185038020887411">"Zgjero: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Palos: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"T\'i jepen aplikacioneve në &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; të njëjtat leje si në &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index d56800958d81..ac84c345b923 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Откажи"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Скролујте надоле на листи"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрелица надоле"</string>
<string name="permission_expand" msgid="893185038020887411">"Прошири <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Скупи <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Апликцијама на уређају &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; дајете све дозволе као на уређају &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 5c6f5ba65525..c9364b8564ef 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Avbryt"</string>
<string name="consent_back" msgid="2560683030046918882">"Tillbaka"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scrolla nedåt i listan"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Nedåtpil"</string>
<string name="permission_expand" msgid="893185038020887411">"Utöka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Komprimera <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vill du ge apparna på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; samma behörigheter som de har på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 7a1cf98832a4..2a9cbee0f2ad 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Ghairi"</string>
<string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Sogeza chini kwenye orodha"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Kishale kinachoelekeza chini"</string>
<string name="permission_expand" msgid="893185038020887411">"Panua <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Kunja <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ungependa kuzipa programu katika &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ruhusa ile ile kama kwenye &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 2313cc3d3b2a..2503826b9074 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ரத்துசெய்"</string>
<string name="consent_back" msgid="2560683030046918882">"பின்செல்"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"பட்டியலில் கீழே நகர்த்து"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"கீழ்நோக்கிய அம்புக்குறி"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ஐ விரிவாக்கும்"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ஐச் சுருக்கும்"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தில் இருக்கும் அதே அனுமதிகளை &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; சாதனத்தில் உள்ள ஆப்ஸுக்கும் வழங்கவா?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index eed0eeef8143..d82c57c3e8fd 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
<string name="consent_cancel" msgid="5655005528379285841">"రద్దు చేయండి"</string>
<string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"లిస్ట్‌ను కిందకు స్క్రోల్ చేయి"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"కింది వైపు బాణం గుర్తు"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>‌ను విస్తరించండి"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>‌ను కుదించండి"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;లోని యాప్‌లకు &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;లో ఉన్న అనుమతులను ఇవ్వాలా?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index bf14f4c529fd..26aa9ddc4205 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
<string name="consent_cancel" msgid="5655005528379285841">"ยกเลิก"</string>
<string name="consent_back" msgid="2560683030046918882">"กลับ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"เลื่อนรายการลง"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ลูกศรชี้ลง"</string>
<string name="permission_expand" msgid="893185038020887411">"ขยาย <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"ยุบ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ให้แอปใน &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; มีสิทธิ์เหมือนกับใน &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ไหม"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 56997d7a09c3..01fc767868d4 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
<string name="consent_cancel" msgid="5655005528379285841">"İptal"</string>
<string name="consent_back" msgid="2560683030046918882">"Geri"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Listeyi aşağı kaydırın"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Aşağı ok"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> panelini genişlet"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> panelini daralt"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazındaki uygulamalara, &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazındakiyle aynı izinler verilsin mi?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 7d7b9dedde31..73e5d585c5a9 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Скасувати"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Прокрутити список униз"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрілка вниз"</string>
<string name="permission_expand" msgid="893185038020887411">"Розгорнути дозвіл \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\""</string>
<string name="permission_collapse" msgid="3320833884220844084">"Згорнути дозвіл \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\""</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Надати додаткам на пристрої &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; такі самі дозволи, що й на пристрої &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index e1a024c985fd..b4ac45c9ceb6 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Bekor qilish"</string>
<string name="consent_back" msgid="2560683030046918882">"Orqaga"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Roʻyxatni pastga varaqlash"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Pastga strelka"</string>
<string name="permission_expand" msgid="893185038020887411">"Yoyish: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Yopish: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovalariga &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasidagi kabi bir xil ruxsatlar berilsinmi?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 029331701fd7..11cceaf2c4d6 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Huỷ"</string>
<string name="consent_back" msgid="2560683030046918882">"Quay lại"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Di chuyển xuống danh sách"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Mũi tên xuống"</string>
<string name="permission_expand" msgid="893185038020887411">"Mở rộng <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Thu gọn <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Cấp cho các ứng dụng trên &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; các quyền giống như trên &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index ed68dd3d08db..7632af0a3ca0 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"不允许"</string>
<string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"向下滚动列表"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"向下箭头"</string>
<string name="permission_expand" msgid="893185038020887411">"展开<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收起<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"要让&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;上的应用享有在&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;上的同等权限吗?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 17d3482f0dbc..9f988c3ff585 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
<string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"向下捲動清單"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"向下箭咀"</string>
<string name="permission_expand" msgid="893185038020887411">"展開<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收合<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; 上的應用程式可獲在 &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; 上的相同權限嗎?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 542a73fc099b..5bc7bfa3781a 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
<string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"向下捲動清單"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"向下箭頭"</string>
<string name="permission_expand" msgid="893185038020887411">"展開<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收合<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"要讓「<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;的應用程式沿用在「<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;上的權限嗎?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index b1c7a14d1210..37034fa6718b 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Khansela"</string>
<string name="consent_back" msgid="2560683030046918882">"Emuva"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Skrola uye ezansi ohlwini"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Umcibisholo obheke phansi"</string>
<string name="permission_expand" msgid="893185038020887411">"Nweba i-<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Goqa i-<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Nikeza ama-app &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; izimvume ezifanayot &lt;strong&gt;njengaku-<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/UniverseProgressNotifier.kt b/packages/EasterEgg/src/com/android/egg/landroid/UniverseProgressNotifier.kt
index bb3a04df6f36..705d9e1cf442 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/UniverseProgressNotifier.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/UniverseProgressNotifier.kt
@@ -127,7 +127,7 @@ class UniverseProgressNotifier(val context: Context, val universe: Universe) {
val eta = if (speed > 0) "%1.0fs".format(distToTarget / speed) else "???"
builder.setContentTitle("headed to: ${target.name}")
builder.setContentText(
- "autopilot is ${autopilot.strategy.toLowerCase()}" +
+ "autopilot is ${autopilot.strategy.lowercase()}" +
"\ndist: ${distToTarget}u // eta: $eta"
)
// fun fact: ProgressStyle was originally EnRouteStyle
diff --git a/packages/SettingsLib/SpaPrivileged/tests/Android.bp b/packages/SettingsLib/SpaPrivileged/tests/unit/Android.bp
index 458fcc97aa9b..458fcc97aa9b 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/Android.bp
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/Android.bp
diff --git a/packages/SettingsLib/SpaPrivileged/tests/AndroidManifest.xml b/packages/SettingsLib/SpaPrivileged/tests/unit/AndroidManifest.xml
index 8d384e8ca02e..8d384e8ca02e 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/AndroidManifest.xml
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/AndroidManifest.xml
diff --git a/packages/SettingsLib/SpaPrivileged/tests/res/values/strings.xml b/packages/SettingsLib/SpaPrivileged/tests/unit/res/values/strings.xml
index bdc0ba8224de..bdc0ba8224de 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/res/values/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/res/values/strings.xml
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt
index 9cb33d2e9b2c..9cb33d2e9b2c 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverAsUserFlowTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt
index 772f925c0a77..772f925c0a77 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BroadcastReceiverFlowTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt
index 7220848eebff..7220848eebff 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/common/BytesFormatterTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
index 4221f9fb5111..4221f9fb5111 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
index fd4b189c51ff..fd4b189c51ff 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
index 4d9d6da582b1..4d9d6da582b1 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
index 74a7c146b2ab..74a7c146b2ab 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt
index 9f80b92548d2..9f80b92548d2 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt
index 97c74411d945..97c74411d945 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppOpsRepositoryTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt
index 70e405557dc7..70e405557dc7 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppRepositoryTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt
index e8ec974bb0b8..e8ec974bb0b8 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/AppStorageRepositoryTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt
index 7f9e98b95fb7..7f9e98b95fb7 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfosTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt
index e10619e01c4e..e10619e01c4e 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagerExtTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt
index 7c928389d08f..7c928389d08f 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PackageManagersTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
index 7ef11eb865ba..7ef11eb865ba 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
index f3245c9085e7..f3245c9085e7 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt
index cd747cc142c1..cd747cc142c1 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBooleanTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt
index c1d298d0b613..c1d298d0b613 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalChangeFlowTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt
index ecc92f8f8d5c..ecc92f8f8d5c 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBooleanTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt
index e3d182bb5ace..e3d182bb5ace 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt
index 72a5bd76e737..72a5bd76e737 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
index 4d90076f060e..4d90076f060e 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt
index 73dd295de77b..73dd295de77b 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListSwitchItemTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
index c6409e7738d6..c6409e7738d6 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt
index d3cfb2d71116..d3cfb2d71116 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItemTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
index 60eccd987724..60eccd987724 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
index 4f42c8254c39..4f42c8254c39 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
index 798e2d49ff57..798e2d49ff57 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
index 79085af63c6d..79085af63c6d 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt
index 1818f2d92f9c..1818f2d92f9c 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt
index e450364a9ab2..e450364a9ab2 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/common/UserProfilePagerTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt
index 55c16bd20336..55c16bd20336 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedMainSwitchPreferenceTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt
index eadf0ca0686d..eadf0ca0686d 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreferenceTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
index 1fd7ecf3cf40..1fd7ecf3cf40 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt
index bdff89f6d69b..bdff89f6d69b 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt
index 4068bceb1475..4068bceb1475 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
index d5e8d6a5fa13..d5e8d6a5fa13 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt
index a7a153ba479c..a7a153ba479c 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestAppListModel.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
index 000743e7ef8a..000743e7ef8a 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt
index 354bbf536a85..354bbf536a85 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/unit/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListProvider.kt
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index a029f56cf1d7..349d13a29b05 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -37,13 +37,6 @@ flag {
}
flag {
- name: "enable_hide_exclusively_managed_bluetooth_device"
- namespace: "dck_framework"
- description: "Hide exclusively managed Bluetooth devices in BT settings menu."
- bug: "324475542"
-}
-
-flag {
name: "enable_set_preferred_transport_for_le_audio_device"
namespace: "bluetooth"
description: "Enable setting preferred transport for Le Audio device"
@@ -249,3 +242,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "audio_stream_media_service_by_receive_state"
+ namespace: "cross_device_experiences"
+ description: "Start or update audio stream media service by receive state"
+ bug: "398700619"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SettingsLib/res/drawable/ic_news.xml b/packages/SettingsLib/res/drawable/ic_news.xml
new file mode 100644
index 000000000000..90615ec1b8fd
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_news.xml
@@ -0,0 +1,19 @@
+<!--
+ ~ Copyright (C) 2025 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="14.933333dp" android:viewportHeight="14" android:viewportWidth="15" android:width="16dp">
+ <path android:fillColor="#ffffff" android:pathData="M3,10.8H11V9.6H3V10.8ZM3,8.4H5.4V4.8H3V8.4ZM12.2,13.6H1.8C1.467,13.6 1.183,13.483 0.95,13.25C0.717,13.017 0.6,12.733 0.6,12.4V3.6C0.6,3.267 0.717,2.983 0.95,2.75C1.183,2.517 1.467,2.4 1.8,2.4H6.683C6.528,2.711 6.406,3.033 6.317,3.367C6.239,3.7 6.2,4.044 6.2,4.4C6.2,4.933 6.283,5.439 6.45,5.917C6.628,6.383 6.878,6.811 7.2,7.2H6.6V8.4H8.767C9.056,8.522 9.35,8.622 9.65,8.7C9.961,8.767 10.278,8.8 10.6,8.8C11.111,8.8 11.606,8.717 12.083,8.55C12.572,8.372 13.011,8.122 13.4,7.8V12.4C13.4,12.733 13.283,13.017 13.05,13.25C12.817,13.483 12.533,13.6 12.2,13.6ZM10.6,8C10.6,7 10.25,6.15 9.55,5.45C8.85,4.75 8,4.4 7,4.4C8,4.4 8.85,4.05 9.55,3.35C10.25,2.65 10.6,1.8 10.6,0.8C10.6,1.8 10.95,2.65 11.65,3.35C12.35,4.05 13.2,4.4 14.2,4.4C13.2,4.4 12.35,4.75 11.65,5.45C10.95,6.15 10.6,7 10.6,8Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_promotions.xml b/packages/SettingsLib/res/drawable/ic_promotions.xml
new file mode 100644
index 000000000000..a597ecebd967
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_promotions.xml
@@ -0,0 +1,19 @@
+<!--
+ ~ Copyright (C) 2025 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="16dp" android:viewportHeight="15" android:viewportWidth="13" android:width="13.866667dp">
+ <path android:fillColor="#ffffff" android:pathData="M1.4,13.4C1.067,13.4 0.783,13.283 0.55,13.05C0.317,12.817 0.2,12.533 0.2,12.2V4.6C0.2,4.267 0.317,3.983 0.55,3.75C0.783,3.517 1.067,3.4 1.4,3.4H2.6V3.133C2.6,2.467 2.822,1.878 3.267,1.367C3.722,0.856 4.3,0.6 5,0.6C5.667,0.6 6.233,0.833 6.7,1.3C7.167,1.767 7.4,2.333 7.4,3V3.4H8.6C8.933,3.4 9.217,3.517 9.45,3.75C9.683,3.983 9.8,4.267 9.8,4.6V6.367C9.611,6.311 9.417,6.272 9.217,6.25C9.017,6.217 8.811,6.2 8.6,6.2C7.378,6.2 6.339,6.628 5.483,7.483C4.628,8.339 4.2,9.378 4.2,10.6C4.2,11.111 4.283,11.611 4.45,12.1C4.628,12.578 4.878,13.011 5.2,13.4H1.4ZM8.6,14.2C8.6,13.2 8.25,12.35 7.55,11.65C6.85,10.95 6,10.6 5,10.6C6,10.6 6.85,10.25 7.55,9.55C8.25,8.85 8.6,8 8.6,7C8.6,8 8.95,8.85 9.65,9.55C10.35,10.25 11.2,10.6 12.2,10.6C11.2,10.6 10.35,10.95 9.65,11.65C8.95,12.35 8.6,13.2 8.6,14.2ZM3.8,3.4H6.2V3C6.2,2.667 6.083,2.383 5.85,2.15C5.617,1.917 5.333,1.8 5,1.8C4.667,1.8 4.383,1.917 4.15,2.15C3.917,2.383 3.8,2.667 3.8,3V3.4ZM3.2,5.8C3.367,5.8 3.506,5.744 3.617,5.633C3.739,5.511 3.8,5.367 3.8,5.2V4.6H2.6V5.2C2.6,5.367 2.656,5.511 2.767,5.633C2.889,5.744 3.033,5.8 3.2,5.8ZM6.8,5.8C6.967,5.8 7.106,5.744 7.217,5.633C7.339,5.511 7.4,5.367 7.4,5.2V4.6H6.2V5.2C6.2,5.367 6.256,5.511 6.367,5.633C6.489,5.744 6.633,5.8 6.8,5.8Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_recs.xml b/packages/SettingsLib/res/drawable/ic_recs.xml
new file mode 100644
index 000000000000..034ff9e221b0
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_recs.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2025 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="14dp"
+ android:height="16dp"
+ android:viewportWidth="14"
+ android:viewportHeight="16">
+ <path
+ android:pathData="M6,15.2L3.6,12.8H1.6C1.278,12.8 0.994,12.683 0.75,12.45C0.517,12.206 0.4,11.922 0.4,11.6V2.8C0.4,2.478 0.517,2.2 0.75,1.967C0.994,1.722 1.278,1.6 1.6,1.6H6.2C5.878,1.989 5.628,2.428 5.45,2.917C5.283,3.394 5.2,3.889 5.2,4.4C5.2,5.622 5.628,6.661 6.483,7.517C7.339,8.372 8.378,8.8 9.6,8.8C9.956,8.8 10.3,8.761 10.633,8.683C10.967,8.594 11.289,8.472 11.6,8.317V11.6C11.6,11.922 11.483,12.206 11.25,12.45C11.017,12.683 10.733,12.8 10.4,12.8H8.4L6,15.2ZM9.6,8C9.6,7 9.25,6.15 8.55,5.45C7.85,4.75 7,4.4 6,4.4C7,4.4 7.85,4.05 8.55,3.35C9.25,2.65 9.6,1.8 9.6,0.8C9.6,1.8 9.95,2.65 10.65,3.35C11.35,4.05 12.2,4.4 13.2,4.4C12.2,4.4 11.35,4.75 10.65,5.45C9.95,6.15 9.6,7 9.6,8Z"
+ android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_social.xml b/packages/SettingsLib/res/drawable/ic_social.xml
new file mode 100644
index 000000000000..01974319b441
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_social.xml
@@ -0,0 +1,19 @@
+<!--
+ ~ Copyright (C) 2025 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="16dp" android:viewportHeight="15" android:viewportWidth="15" android:width="16dp">
+ <path android:fillColor="#ffffff" android:pathData="M0.6,14.4V12.733C0.6,12.411 0.678,12.117 0.833,11.85C0.989,11.583 1.211,11.378 1.5,11.233C2.056,10.956 2.628,10.75 3.217,10.617C3.817,10.472 4.428,10.4 5.05,10.4C5.661,10.4 6.256,10.472 6.833,10.617C7.422,10.75 7.989,10.956 8.533,11.233C8.811,11.378 9.028,11.583 9.183,11.85C9.339,12.117 9.417,12.411 9.417,12.733V14.4H0.6ZM10.6,14.4V12.617C10.6,12.183 10.494,11.778 10.283,11.4C10.072,11.022 9.772,10.733 9.383,10.533C9.772,10.6 10.144,10.7 10.5,10.833C10.856,10.956 11.206,11.106 11.55,11.283C11.828,11.439 12.072,11.628 12.283,11.85C12.494,12.061 12.6,12.317 12.6,12.617V14.4H10.6ZM5.2,9.6C4.589,9.6 4.067,9.389 3.633,8.967C3.211,8.533 3,8.011 3,7.4C3,6.789 3.211,6.272 3.633,5.85C4.067,5.417 4.589,5.2 5.2,5.2C5.811,5.2 6.328,5.417 6.75,5.85C7.183,6.272 7.4,6.789 7.4,7.4C7.4,8.011 7.183,8.533 6.75,8.967C6.328,9.389 5.811,9.6 5.2,9.6ZM10.6,7.4C10.6,8.011 10.383,8.533 9.95,8.967C9.528,9.389 9.011,9.6 8.4,9.6C8.311,9.6 8.217,9.594 8.117,9.583C8.017,9.572 7.922,9.55 7.833,9.517C8.089,9.206 8.278,8.872 8.4,8.517C8.533,8.161 8.6,7.789 8.6,7.4C8.6,7.011 8.533,6.639 8.4,6.283C8.278,5.928 8.089,5.594 7.833,5.283C7.922,5.25 8.017,5.228 8.117,5.217C8.217,5.206 8.311,5.2 8.4,5.2C9.011,5.2 9.528,5.417 9.95,5.85C10.383,6.272 10.6,6.789 10.6,7.4ZM11.4,6.4C11.4,5.622 11.128,4.961 10.583,4.417C10.039,3.872 9.378,3.6 8.6,3.6C9.378,3.6 10.039,3.328 10.583,2.783C11.128,2.239 11.4,1.578 11.4,0.8C11.4,1.578 11.672,2.239 12.217,2.783C12.761,3.328 13.422,3.6 14.2,3.6C13.422,3.6 12.761,3.872 12.217,4.417C11.672,4.961 11.4,5.622 11.4,6.4Z"/>
+</vector>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index e78a69239334..ae9ad958b287 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -51,6 +51,8 @@ import com.android.settingslib.widget.AdaptiveOutlineDrawable;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -1268,4 +1270,15 @@ public class BluetoothUtils {
return false;
}
+
+ /** Gets key missing count of the device. This is a workaround before the API is rolled out. */
+ public static Integer getKeyMissingCount(BluetoothDevice device) {
+ try {
+ Method m = BluetoothDevice.class.getDeclaredMethod("getKeyMissingCount");
+ return (int) m.invoke(device);
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ Log.w(TAG, "error happens when getKeyMissingCount.");
+ return null;
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index 88bccc9f6ebd..2ed437c94439 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -509,6 +509,7 @@ open class WifiUtils {
val intent = AdvancedProtectionManager.createSupportIntent(
AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION)
+ intent.putExtra(DIALOG_WINDOW_TYPE, dialogWindowType)
onStartActivity(intent)
} else if (wifiManager.isWepSupported == true && wifiManager.queryWepAllowed()) {
onAllowed()
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index dafcc729b8f1..d929b0de391a 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -187,6 +187,9 @@
<!-- Default state of tap to wake -->
<bool name="def_double_tap_to_wake">true</bool>
+ <!-- Default setting for double tap to sleep (Settings.Secure.DOUBLE_TAP_TO_SLEEP) -->
+ <bool name="def_double_tap_to_sleep">false</bool>
+
<!-- Default for Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT -->
<string name="def_nfc_payment_component"></string>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index c0105298899b..f0a0483aa17c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -85,6 +85,7 @@ public class SecureSettings {
Settings.Secure.MOUNT_UMS_PROMPT,
Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
Settings.Secure.DOUBLE_TAP_TO_WAKE,
+ Settings.Secure.DOUBLE_TAP_TO_SLEEP,
Settings.Secure.WAKE_GESTURE_ENABLED,
Settings.Secure.LONG_PRESS_TIMEOUT,
Settings.Secure.KEY_REPEAT_ENABLED,
@@ -293,5 +294,7 @@ public class SecureSettings {
Settings.Secure.FINGERPRINT_APP_ENABLED,
Settings.Secure.FINGERPRINT_KEYGUARD_ENABLED,
Settings.Secure.DUAL_SHADE,
+ Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED,
+ Settings.Secure.SEARCH_CONTENT_FILTERS_ENABLED,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 0ffdf53f2036..b5de7e719043 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -131,6 +131,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.MOUNT_UMS_PROMPT, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.MOUNT_UMS_NOTIFY_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DOUBLE_TAP_TO_WAKE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOUBLE_TAP_TO_SLEEP, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.WAKE_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LONG_PRESS_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.KEY_REPEAT_ENABLED, BOOLEAN_VALIDATOR);
@@ -461,5 +462,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.FINGERPRINT_APP_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.FINGERPRINT_KEYGUARD_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DUAL_SHADE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.BROWSER_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SEARCH_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index de7c450d8d39..7c975b750639 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -72,6 +72,7 @@ import java.util.regex.Pattern;
public final class DeviceConfigService extends Binder {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
+ "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index bc281eea39d8..65ede9d804d0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -396,6 +396,8 @@ public class SettingsProvider extends ContentProvider {
private volatile SystemConfigManager mSysConfigManager;
+ private PackageMonitor mPackageMonitor;
+
@GuardedBy("mLock")
private boolean mSyncConfigDisabledUntilReboot;
@@ -403,6 +405,7 @@ public class SettingsProvider extends ContentProvider {
@EnabledSince(targetSdkVersion=android.os.Build.VERSION_CODES.S)
private static final long ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL = 172670679L;
+
@Override
public boolean onCreate() {
Settings.setInSystemServer();
@@ -1036,7 +1039,7 @@ public class SettingsProvider extends ContentProvider {
}
}, userFilter);
- PackageMonitor monitor = new PackageMonitor() {
+ mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
@@ -1062,7 +1065,7 @@ public class SettingsProvider extends ContentProvider {
};
// package changes
- monitor.register(getContext(), BackgroundThread.getHandler().getLooper(),
+ mPackageMonitor.register(getContext(), BackgroundThread.getHandler().getLooper(),
UserHandle.ALL, true);
}
@@ -4077,7 +4080,7 @@ public class SettingsProvider extends ContentProvider {
@VisibleForTesting
final class UpgradeController {
- private static final int SETTINGS_VERSION = 227;
+ private static final int SETTINGS_VERSION = 228;
private final int mUserId;
@@ -6316,6 +6319,23 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 227;
}
+ // Version 227: Add default value for DOUBLE_TAP_TO_SLEEP.
+ if (currentVersion == 227) {
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ final Setting doubleTapToSleep = secureSettings.getSettingLocked(
+ Settings.Secure.DOUBLE_TAP_TO_SLEEP);
+ if (doubleTapToSleep.isNull()) {
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.DOUBLE_TAP_TO_SLEEP,
+ getContext().getResources().getBoolean(
+ R.bool.def_double_tap_to_sleep) ? "1" : "0",
+ null /* tag */,
+ true /* makeDefault */,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ currentVersion = 228;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 99c4e21c6053..17c13b78778c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -158,6 +158,7 @@ public class SettingsState {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
+ "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
diff --git a/packages/Shell/res/values-et/strings.xml b/packages/Shell/res/values-et/strings.xml
index 48c73345ddcc..c18687fd18ff 100644
--- a/packages/Shell/res/values-et/strings.xml
+++ b/packages/Shell/res/values-et/strings.xml
@@ -21,7 +21,7 @@
<string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luuakse veaaruannet <xliff:g id="ID">#%d</xliff:g>"</string>
<string name="bugreport_finished_title" msgid="4429132808670114081">"Jäädvustati veaaruanne <xliff:g id="ID">#%d</xliff:g>"</string>
<string name="bugreport_updating_title" msgid="4423539949559634214">"Üksikasjade lisamine veaaruandesse"</string>
- <string name="bugreport_updating_wait" msgid="3322151947853929470">"Oodake …"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Palun oodake…"</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Veaaruanne kuvatakse telefonis peagi"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Veaaruande jagamiseks valige"</string>
<string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Veaaruande jagamiseks puudutage"</string>
diff --git a/packages/SystemUI/aconfig/predictive_back.aconfig b/packages/SystemUI/aconfig/predictive_back.aconfig
index ee918c275b7b..89a0d895a17c 100644
--- a/packages/SystemUI/aconfig/predictive_back.aconfig
+++ b/packages/SystemUI/aconfig/predictive_back.aconfig
@@ -7,3 +7,10 @@ flag {
description: "Enable Shade Animations"
bug: "327732946"
}
+
+flag {
+ name: "predictive_back_delay_transition"
+ namespace: "systemui"
+ description: "Slightly delays the back transition start"
+ bug: "301195601"
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a90081738062..9db4346a08b7 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -2102,4 +2102,11 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
-} \ No newline at end of file
+}
+
+flag {
+ name: "move_transition_animation_layer"
+ namespace: "systemui"
+ description: "Enables moving the launching window on top of the origin window in the Animation library."
+ bug: "390422470"
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index f03bd3d9a2a7..e43b8a0b9297 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -62,6 +62,7 @@ import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.systemui.Flags.activityTransitionUseLargestWindow
+import com.android.systemui.Flags.moveTransitionAnimationLayer
import com.android.systemui.Flags.translucentOccludingActivityFix
import com.android.systemui.animation.TransitionAnimator.Companion.assertLongLivedReturnAnimations
import com.android.systemui.animation.TransitionAnimator.Companion.assertReturnAnimations
@@ -1514,6 +1515,20 @@ constructor(
)
}
+ if (moveTransitionAnimationLayer()) {
+ // Ensure that the launching window is rendered above the view's window,
+ // so it is not obstructed.
+ // TODO(b/397180418): re-use the start transaction once the
+ // RemoteAnimation wrapper is cleaned up.
+ SurfaceControl.Transaction().use {
+ it.reparent(
+ window.leash,
+ controller.transitionContainer.viewRootImpl.surfaceControl,
+ )
+ it.apply()
+ }
+ }
+
if (startTransaction != null) {
// Calling applyStateToWindow() here avoids skipping a frame when taking
// over an animation.
@@ -1566,12 +1581,18 @@ constructor(
} else {
null
}
+ val fadeWindowBackgroundLayer =
+ if (moveTransitionAnimationLayer()) {
+ false
+ } else {
+ !controller.isBelowAnimatingWindow
+ }
animation =
transitionAnimator.startAnimation(
controller,
endState,
windowBackgroundColor,
- fadeWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
+ fadeWindowBackgroundLayer = fadeWindowBackgroundLayer,
drawHole = !controller.isBelowAnimatingWindow,
startVelocity = velocityPxPerS,
startFrameTime = windowState?.timestamp ?: -1,
@@ -1685,7 +1706,7 @@ constructor(
// fade in progressively. Otherwise, it should be fully opaque and will be progressively
// revealed as the window background color layer above the window fades out.
val alpha =
- if (controller.isBelowAnimatingWindow) {
+ if (moveTransitionAnimationLayer() || controller.isBelowAnimatingWindow) {
if (controller.isLaunching) {
interpolators.contentAfterFadeInInterpolator.getInterpolation(
windowProgress
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt
index f4e03613169a..e734dd26eb15 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt
@@ -25,6 +25,7 @@ data class AxisDefinition(
)
object GSFAxes {
+ @JvmStatic
val WEIGHT =
AxisDefinition(
tag = "wght",
@@ -91,8 +92,8 @@ object GSFAxes {
private val AXIS_MAP =
listOf(WEIGHT, WIDTH, SLANT, ROUND, GRADE, OPTICAL_SIZE, ITALIC)
- .map { def -> def.tag.toLowerCase() to def }
+ .map { def -> def.tag.lowercase() to def }
.toMap()
- fun getAxis(axis: String): AxisDefinition? = AXIS_MAP[axis.toLowerCase()]
+ fun getAxis(axis: String): AxisDefinition? = AXIS_MAP[axis.lowercase()]
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 5b073e49192a..4a39cff388a9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -39,6 +39,7 @@ interface TypefaceVariantCache {
fun getTypefaceForVariant(fvar: String?): Typeface?
companion object {
+ @JvmStatic
fun createVariantTypeface(baseTypeface: Typeface, fVar: String?): Typeface {
if (fVar.isNullOrEmpty()) {
return baseTypeface
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index 4e889e946a5f..5d9c441db003 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -39,6 +39,7 @@ import com.android.app.animation.Interpolators.LINEAR
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.dynamicanimation.animation.SpringAnimation
import com.android.internal.dynamicanimation.animation.SpringForce
+import com.android.systemui.Flags.moveTransitionAnimationLayer
import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
import com.android.systemui.shared.Flags.returnAnimationFrameworkLongLived
import java.util.concurrent.Executor
@@ -509,6 +510,8 @@ class TransitionAnimator(
* punching a hole in the [transition container][Controller.transitionContainer]) iff [drawHole]
* is true.
*
+ * TODO(b/397646693): remove drawHole altogether.
+ *
* If [startVelocity] (expressed in pixels per second) is not null, a multi-spring animation
* using it for the initial momentum will be used instead of the default interpolators. In this
* case, [startFrameTime] (if non-negative) represents the frame time at which the springs
@@ -1183,6 +1186,10 @@ class TransitionAnimator(
if (drawHole) {
drawable.setXfermode(SRC_MODE)
}
+ } else if (moveTransitionAnimationLayer() && fadeOutProgress >= 1 && drawHole) {
+ // If [drawHole] is true, draw it once the opening content is done fading in.
+ drawable.alpha = 0x00
+ drawable.setXfermode(SRC_MODE)
} else {
drawable.alpha = 0xFF
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/PagerDots.kt
index 91f1477d5325..172d88af4cc8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/PagerDots.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.compose
+package com.android.systemui.common.ui.compose
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.Canvas
@@ -43,9 +43,9 @@ import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
+import com.android.app.tracing.coroutines.launchTraced as launch
import kotlin.math.absoluteValue
import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
import platform.test.motion.compose.values.MotionTestValueKey
import platform.test.motion.compose.values.motionTestValues
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 4e1aab58ac24..3150e94908cd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -182,7 +182,7 @@ fun CommunalContainer(
viewModel.communalBackground.collectAsStateWithLifecycle(
initialValue = CommunalBackgroundType.ANIMATED
)
- val swipeToHubEnabled by viewModel.swipeToHubEnabled.collectAsStateWithLifecycle()
+ val swipeToHubEnabled by viewModel.swipeToHubEnabled.collectAsStateWithLifecycle(false)
val state: MutableSceneTransitionLayoutState =
rememberMutableSceneTransitionLayoutState(
initialScene = currentSceneKey,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 547461e5faf2..a0216268308c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -49,6 +49,8 @@ import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
+import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.modifiers.thenIf
import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
@@ -258,7 +260,11 @@ fun ContentScope.QuickSettingsLayout(
BrightnessSliderContainer(
viewModel = viewModel.brightnessSliderViewModel,
containerColor = OverlayShade.Colors.PanelBackground,
- modifier = Modifier.systemGestureExclusionInShade().fillMaxWidth(),
+ modifier =
+ Modifier.systemGestureExclusionInShade(
+ enabled = { layoutState.transitionState is TransitionState.Idle }
+ )
+ .fillMaxWidth(),
)
Box {
@@ -289,18 +295,20 @@ object QuickSettingsShade {
* right.
*/
@Composable
- fun Modifier.systemGestureExclusionInShade(): Modifier {
+ fun Modifier.systemGestureExclusionInShade(enabled: () -> Boolean): Modifier {
val density = LocalDensity.current
- return systemGestureExclusion { layoutCoordinates ->
- val sidePadding = with(density) { Dimensions.Padding.toPx() }
- Rect(
- offset = Offset(x = -sidePadding, y = 0f),
- size =
- Size(
- width = layoutCoordinates.size.width.toFloat() + 2 * sidePadding,
- height = layoutCoordinates.size.height.toFloat(),
- ),
- )
+ return thenIf(enabled()) {
+ Modifier.systemGestureExclusion { layoutCoordinates ->
+ val sidePadding = with(density) { Dimensions.Padding.toPx() }
+ Rect(
+ offset = Offset(x = -sidePadding, y = 0f),
+ size =
+ Size(
+ width = layoutCoordinates.size.width.toFloat() + 2 * sidePadding,
+ height = layoutCoordinates.size.height.toFloat(),
+ ),
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 0c502e6f492d..7015f79e4a9f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -56,6 +56,7 @@ import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.view.SceneJankMonitor
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
+import com.android.systemui.shade.ui.composable.OverlayShade
import com.android.systemui.shade.ui.composable.isFullWidthShade
import javax.inject.Provider
@@ -100,9 +101,13 @@ fun SceneContainer(
rememberActivated(traceName = "sceneJankMonitor") { sceneJankMonitorFactory.create() }
val hapticFeedback = LocalHapticFeedback.current
+ val shadeExpansionMotion = OverlayShade.rememberShadeExpansionMotion()
val sceneTransitions =
- remember(hapticFeedback) {
- transitionsBuilder.build(viewModel.hapticsViewModel.getRevealHaptics(hapticFeedback))
+ remember(hapticFeedback, shadeExpansionMotion) {
+ transitionsBuilder.build(
+ shadeExpansionMotion,
+ viewModel.hapticsViewModel.getRevealHaptics(hapticFeedback),
+ )
}
val state =
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 7fe19fe70a25..9b45ef693ce6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -6,6 +6,7 @@ import com.android.compose.animation.scene.TransitionKey
import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
import com.android.compose.animation.scene.transitions
import com.android.internal.jank.Cuj
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
@@ -48,7 +49,10 @@ import com.android.systemui.shade.ui.composable.Shade
* Please keep the list sorted alphabetically.
*/
class SceneContainerTransitions : SceneContainerTransitionsBuilder {
- override fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions {
+ override fun build(
+ shadeExpansionMotion: EdgeContainerExpansionSpec,
+ revealHaptics: ContainerRevealHaptics,
+ ): SceneTransitions {
return transitions {
interruptionHandler = DefaultInterruptionHandler
@@ -201,13 +205,19 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
Overlays.NotificationsShade,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
) {
- toNotificationsShadeTransition(revealHaptics = revealHaptics)
+ toNotificationsShadeTransition(
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
to(
Overlays.QuickSettingsShade,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
) {
- toQuickSettingsShadeTransition(revealHaptics = revealHaptics)
+ toQuickSettingsShadeTransition(
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
from(
Scenes.Gone,
@@ -215,7 +225,11 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
key = SlightlyFasterShadeCollapse,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
) {
- toNotificationsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+ toNotificationsShadeTransition(
+ durationScale = 0.9,
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
from(
Scenes.Gone,
@@ -223,7 +237,11 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
key = SlightlyFasterShadeCollapse,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
) {
- toQuickSettingsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+ toQuickSettingsShadeTransition(
+ durationScale = 0.9,
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
from(
Scenes.Lockscreen,
@@ -231,7 +249,11 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
key = SlightlyFasterShadeCollapse,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
) {
- toNotificationsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+ toNotificationsShadeTransition(
+ durationScale = 0.9,
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
from(
Scenes.Lockscreen,
@@ -239,7 +261,11 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
key = SlightlyFasterShadeCollapse,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
) {
- toQuickSettingsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+ toQuickSettingsShadeTransition(
+ durationScale = 0.9,
+ shadeExpansionMotion = shadeExpansionMotion,
+ revealHaptics = revealHaptics,
+ )
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
index 13d3456baa74..eb5548d45247 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
@@ -19,6 +19,7 @@ package com.android.systemui.scene.ui.composable
import com.android.compose.animation.scene.SceneTransitions
import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
import com.android.compose.animation.scene.transitions
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
/**
* Builder of the comprehensive definition of all transitions between scenes and overlays in the
@@ -27,7 +28,10 @@ import com.android.compose.animation.scene.transitions
interface SceneContainerTransitionsBuilder {
/** Build the [SceneContainer] transitions spec. */
- fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions
+ fun build(
+ shadeExpansionMotion: EdgeContainerExpansionSpec,
+ revealHaptics: ContainerRevealHaptics,
+ ): SceneTransitions
}
/**
@@ -37,5 +41,8 @@ interface SceneContainerTransitionsBuilder {
class ConstantSceneContainerTransitionsBuilder(
private val transitions: SceneTransitions = transitions { /* No transitions */ }
) : SceneContainerTransitionsBuilder {
- override fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions = transitions
+ override fun build(
+ shadeExpansionMotion: EdgeContainerExpansionSpec,
+ revealHaptics: ContainerRevealHaptics,
+ ): SceneTransitions = transitions
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
index 722af6ae4f34..9b4b91eb23c1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
@@ -20,6 +20,7 @@ import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
import com.android.compose.animation.scene.reveal.verticalContainerReveal
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
import com.android.systemui.notifications.ui.composable.NotificationsShade
import com.android.systemui.scene.shared.model.Overlays
@@ -28,6 +29,7 @@ import kotlin.time.Duration.Companion.milliseconds
fun TransitionBuilder.toNotificationsShadeTransition(
durationScale: Double = 1.0,
+ shadeExpansionMotion: EdgeContainerExpansionSpec,
revealHaptics: ContainerRevealHaptics,
) {
spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
@@ -38,7 +40,7 @@ fun TransitionBuilder.toNotificationsShadeTransition(
elevateInContent = Overlays.NotificationsShade,
)
- verticalContainerReveal(NotificationsShade.Elements.Panel, revealHaptics)
+ verticalContainerReveal(NotificationsShade.Elements.Panel, shadeExpansionMotion, revealHaptics)
fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
fractionRange(start = .5f) { fade(NotificationsShade.Elements.StatusBar) }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
index 3cce99740e47..47dd85f17cee 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
@@ -20,17 +20,19 @@ import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
import com.android.compose.animation.scene.reveal.verticalContainerReveal
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
import com.android.systemui.qs.ui.composable.QuickSettingsShade
import com.android.systemui.shade.ui.composable.OverlayShade
import kotlin.time.Duration.Companion.milliseconds
fun TransitionBuilder.toQuickSettingsShadeTransition(
durationScale: Double = 1.0,
+ shadeExpansionMotion: EdgeContainerExpansionSpec,
revealHaptics: ContainerRevealHaptics,
) {
spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
- verticalContainerReveal(QuickSettingsShade.Elements.Panel, revealHaptics)
+ verticalContainerReveal(QuickSettingsShade.Elements.Panel, shadeExpansionMotion, revealHaptics)
fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
fractionRange(start = .5f) { fade(QuickSettingsShade.Elements.StatusBar) }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
index 7e7b6297406e..3446081fb123 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
@@ -37,24 +37,26 @@ import androidx.compose.foundation.layout.systemBarsIgnoringVisibility
import androidx.compose.foundation.layout.waterfall
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.overscroll
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexContentPicker
import com.android.compose.windowsizeclass.LocalWindowSizeClass
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.edgeContainerExpansionBackground
import com.android.systemui.res.R
-import androidx.compose.ui.unit.Dp
+import com.android.systemui.shade.ui.composable.OverlayShade.rememberShadeExpansionMotion
/** Renders a lightweight shade UI container, as an overlay. */
@Composable
@@ -110,23 +112,15 @@ private fun ContentScope.Panel(
) {
Box(
modifier =
- modifier.clip(OverlayShade.Shapes.RoundedCornerPanel).disableSwipesWhenScrolling()
+ modifier
+ .disableSwipesWhenScrolling()
+ .edgeContainerExpansionBackground(
+ OverlayShade.Colors.PanelBackground,
+ rememberShadeExpansionMotion(),
+ )
) {
- Spacer(
- modifier =
- Modifier.element(OverlayShade.Elements.PanelBackground)
- .matchParentSize()
- .background(
- color = OverlayShade.Colors.PanelBackground,
- shape = OverlayShade.Shapes.RoundedCornerPanel,
- )
- )
-
Column {
header?.invoke()
-
- // This content is intentionally rendered as a separate element from the background in
- // order to allow for more flexibility when defining transitions.
content()
}
}
@@ -192,8 +186,6 @@ object OverlayShade {
contentPicker = LowestZIndexContentPicker,
placeAllCopies = true,
)
- val PanelBackground =
- ElementKey("OverlayShadePanelBackground", contentPicker = LowestZIndexContentPicker)
}
object Colors {
@@ -205,13 +197,13 @@ object OverlayShade {
object Dimensions {
val PanelCornerRadius: Dp
@Composable
- @ReadOnlyComposable get() =
- dimensionResource(R.dimen.overlay_shade_panel_shape_radius)
+ @ReadOnlyComposable
+ get() = dimensionResource(R.dimen.overlay_shade_panel_shape_radius)
}
- object Shapes {
- val RoundedCornerPanel: RoundedCornerShape
- @Composable
- @ReadOnlyComposable get() = RoundedCornerShape(Dimensions.PanelCornerRadius)
+ @Composable
+ fun rememberShadeExpansionMotion(): EdgeContainerExpansionSpec {
+ val radius = Dimensions.PanelCornerRadius
+ return remember(radius) { EdgeContainerExpansionSpec(radius = radius) }
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
index 2134510557d0..72f9bd5da742 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
@@ -16,28 +16,20 @@
package com.android.compose.animation.scene.reveal
-import androidx.compose.animation.core.AnimationVector1D
-import androidx.compose.animation.core.DeferredTargetAnimation
-import androidx.compose.animation.core.ExperimentalAnimatableApi
-import androidx.compose.animation.core.FiniteAnimationSpec
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.spring
-import androidx.compose.ui.unit.Dp
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.util.fastCoerceAtLeast
-import androidx.compose.ui.util.fastCoerceAtMost
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ElementKey
-import com.android.compose.animation.scene.OverlayKey
-import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.UserActionDistance
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.mechanics.MotionValueInput
+import com.android.compose.animation.scene.mechanics.TransitionScopedMechanicsAdapter
import com.android.compose.animation.scene.transformation.CustomPropertyTransformation
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.PropertyTransformationScope
-import kotlin.math.roundToInt
+import com.android.mechanics.MotionValue
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
import kotlinx.coroutines.CoroutineScope
interface ContainerRevealHaptics {
@@ -53,9 +45,15 @@ interface ContainerRevealHaptics {
fun onRevealThresholdCrossed(revealed: Boolean)
}
-/** Animate the reveal of [container] by animating its size. */
+/**
+ * Animate the reveal of [container] by animating its size.
+ *
+ * This implicitly sets the [distance] of the transition to the target size of [container]
+ */
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
fun TransitionBuilder.verticalContainerReveal(
container: ElementKey,
+ motionSpec: EdgeContainerExpansionSpec,
haptics: ContainerRevealHaptics,
) {
// Make the swipe distance be exactly the target height of the container.
@@ -76,188 +74,73 @@ fun TransitionBuilder.verticalContainerReveal(
(targetSizeInToContent?.height ?: targetSizeInFromContent?.height)?.toFloat() ?: 0f
}
- // TODO(b/376438969): Improve the motion of this gesture using Motion Mechanics.
-
- // The min distance to swipe before triggering the reveal spring.
- val distanceThreshold = 80.dp
-
- // The minimum height of the container.
- val minHeight = 10.dp
-
- // The amount removed from the container width at 0% progress.
- val widthDelta = 140.dp
-
- // The ratio at which the distance is tracked before reaching the threshold, e.g. if the user
- // drags 60dp then the height will be 60dp * 0.25f = 15dp.
- val trackingRatio = 0.25f
-
- // The max progress starting from which the container should always be visible, even if we are
- // animating the container out. This is used so that we don't immediately fade out the container
- // when triggering a one-off animation that hides it.
- val alphaProgressThreshold = 0.05f
-
- // The spring animating the size of the container.
- val sizeSpec = spring<Float>(stiffness = 380f, dampingRatio = 0.9f)
-
- // The spring animating the alpha of the container.
- val alphaSpec = spring<Float>(stiffness = 1200f, dampingRatio = 0.99f)
-
- // Size transformation.
- transformation(container) {
- VerticalContainerRevealSizeTransformation(
- haptics,
- distanceThreshold,
- trackingRatio,
- minHeight,
- widthDelta,
- sizeSpec,
- )
- }
-
- // Alpha transformation.
- transformation(container) {
- ContainerRevealAlphaTransformation(alphaSpec, alphaProgressThreshold)
- }
-}
-
-@OptIn(ExperimentalAnimatableApi::class)
-private class VerticalContainerRevealSizeTransformation(
- private val haptics: ContainerRevealHaptics,
- private val distanceThreshold: Dp,
- private val trackingRatio: Float,
- private val minHeight: Dp,
- private val widthDelta: Dp,
- private val spec: FiniteAnimationSpec<Float>,
-) : CustomPropertyTransformation<IntSize> {
- override val property = PropertyTransformation.Property.Size
-
- private val widthAnimation = DeferredTargetAnimation(Float.VectorConverter)
- private val heightAnimation = DeferredTargetAnimation(Float.VectorConverter)
-
- private var previousHasReachedThreshold: Boolean? = null
-
- override fun PropertyTransformationScope.transform(
- content: ContentKey,
- element: ElementKey,
- transition: TransitionState.Transition,
- transitionScope: CoroutineScope,
- ): IntSize {
- // The distance to go to 100%. Note that we don't use
- // TransitionState.HasOverscrollProperties.absoluteDistance because the transition will not
- // implement HasOverscrollProperties if the transition is triggered and not gesture based.
+ // TODO(b/392534646) Add haptics back
+ val heightInput: MotionValueInput = { progress, content, element ->
val idleSize = checkNotNull(element.targetSize(content))
- val userActionDistance = idleSize.height
- val progress = transition.progressTo(content)
- val distance = (progress * userActionDistance).fastCoerceAtLeast(0f)
- val threshold = distanceThreshold.toPx()
-
- // Width.
- val widthDelta = widthDelta.toPx()
- val width =
- (idleSize.width - widthDelta +
- animateSize(
- size = widthDelta,
- distance = distance,
- threshold = threshold,
- transitionScope = transitionScope,
- animation = widthAnimation,
- ))
- .roundToInt()
-
- // Height.
- val minHeight = minHeight.toPx()
- val height =
- (
- // 1) The minimum size of the container.
- minHeight +
-
- // 2) The animated size between the minimum size and the threshold.
- animateSize(
- size = threshold - minHeight,
- distance = distance,
- threshold = threshold,
- transitionScope = transitionScope,
- animation = heightAnimation,
- ) +
-
- // 3) The remaining height after the threshold, tracking the finger.
- (distance - threshold).fastCoerceAtLeast(0f))
- .roundToInt()
- .fastCoerceAtMost(idleSize.height)
-
- // Haptics.
- val hasReachedThreshold = distance >= threshold
- if (
- previousHasReachedThreshold != null &&
- hasReachedThreshold != previousHasReachedThreshold &&
- transition.isUserInputOngoing
- ) {
- haptics.onRevealThresholdCrossed(revealed = hasReachedThreshold)
- }
- previousHasReachedThreshold = hasReachedThreshold
-
- return IntSize(width = width, height = height)
+ val targetHeight = idleSize.height.toFloat()
+ targetHeight * progress
}
- /**
- * Animate a size up to [size], so that it is equal to 0f when distance is 0f and equal to
- * [size] when `distance >= threshold`, taking the [trackingRatio] into account.
- */
- @OptIn(ExperimentalAnimatableApi::class)
- private fun animateSize(
- size: Float,
- distance: Float,
- threshold: Float,
- transitionScope: CoroutineScope,
- animation: DeferredTargetAnimation<Float, AnimationVector1D>,
- ): Float {
- val trackingSize = distance.fastCoerceAtMost(threshold) / threshold * size * trackingRatio
- val springTarget =
- if (distance >= threshold) {
- size * (1f - trackingRatio)
- } else {
- 0f
+ transformation(container) {
+ object : CustomPropertyTransformation<IntSize> {
+ override val property = PropertyTransformation.Property.Size
+
+ val heightValue =
+ TransitionScopedMechanicsAdapter(
+ computeInput = heightInput,
+ stableThreshold = MotionValue.StableThresholdSpatial,
+ label = "verticalContainerReveal::height",
+ ) { _, _ ->
+ motionSpec.createHeightSpec(motionScheme, density = this)
+ }
+ val widthValue =
+ TransitionScopedMechanicsAdapter(
+ computeInput = heightInput,
+ stableThreshold = MotionValue.StableThresholdSpatial,
+ label = "verticalContainerReveal::width",
+ ) { content, element ->
+ val idleSize = checkNotNull(element.targetSize(content))
+ val intrinsicWidth = idleSize.width.toFloat()
+ motionSpec.createWidthSpec(intrinsicWidth, motionScheme, density = this)
+ }
+
+ override fun PropertyTransformationScope.transform(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ transitionScope: CoroutineScope,
+ ): IntSize {
+
+ val height =
+ with(heightValue) { update(content, element, transition, transitionScope) }
+ val width =
+ with(widthValue) { update(content, element, transition, transitionScope) }
+
+ return IntSize(width.toInt(), height.toInt())
}
- val springSize = animation.updateTarget(springTarget, transitionScope, spec)
- return trackingSize + springSize
- }
-}
-
-@OptIn(ExperimentalAnimatableApi::class)
-private class ContainerRevealAlphaTransformation(
- private val spec: FiniteAnimationSpec<Float>,
- private val progressThreshold: Float,
-) : CustomPropertyTransformation<Float> {
- override val property = PropertyTransformation.Property.Alpha
- private val alphaAnimation = DeferredTargetAnimation(Float.VectorConverter)
-
- override fun PropertyTransformationScope.transform(
- content: ContentKey,
- element: ElementKey,
- transition: TransitionState.Transition,
- transitionScope: CoroutineScope,
- ): Float {
- return alphaAnimation.updateTarget(targetAlpha(transition, content), transitionScope, spec)
- }
-
- private fun targetAlpha(transition: TransitionState.Transition, content: ContentKey): Float {
- if (transition.isUserInputOngoing) {
- return if (transition.progressTo(content) > 0f) 1f else 0f
}
+ }
- // The transition was committed (the user released their finger), so the alpha depends on
- // whether we are animating towards the content (showing the container) or away from it
- // (hiding the container).
- val isShowingContainer =
- when (content) {
- is SceneKey -> transition.currentScene == content
- is OverlayKey -> transition.currentOverlays.contains(content)
+ transformation(container) {
+ object : CustomPropertyTransformation<Float> {
+
+ override val property = PropertyTransformation.Property.Alpha
+ val alphaValue =
+ TransitionScopedMechanicsAdapter(
+ computeInput = heightInput,
+ label = "verticalContainerReveal::alpha",
+ ) { _, _ ->
+ motionSpec.createAlphaSpec(motionScheme, density = this)
+ }
+
+ override fun PropertyTransformationScope.transform(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ transitionScope: CoroutineScope,
+ ): Float {
+ return with(alphaValue) { update(content, element, transition, transitionScope) }
}
-
- return if (isShowingContainer || transition.progressTo(content) >= progressThreshold) {
- 1f
- } else {
- 0f
}
}
}
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json
index ce62ac3f4ee2..a2f8863a34f7 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json
@@ -24,7 +24,6 @@
336,
352,
368,
- 384,
"after"
],
"features": [
@@ -38,29 +37,28 @@
{
"type": "not_found"
},
- 175,
- 175,
- 174.00105,
- 149.84001,
- 114.73702,
+ 125,
+ 125,
+ 124.28647,
+ 107.02858,
+ 81.95502,
0,
0,
0,
0,
- 10.212692,
- 42.525528,
- 77.174965,
- 106.322296,
- 128.37651,
- 144.09671,
- 154.88022,
- 162.08202,
- 166.79778,
- 169.83923,
- 171.77742,
- 173.00056,
- 173.76627,
- 174.24236,
+ 7.2947845,
+ 30.375374,
+ 55.12497,
+ 75.944496,
+ 91.69751,
+ 102.92622,
+ 110.62873,
+ 115.772865,
+ 119.141266,
+ 121.313736,
+ 122.69816,
+ 123.57184,
+ 124.11877,
{
"type": "not_found"
}
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json
index ac09ff3f359c..bda53bbf3e6c 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json
@@ -24,23 +24,23 @@
"name": "Foo_yOffset",
"type": "float",
"data_points": [
- 175,
- 175,
- 175,
- 175,
- 156.26086,
- 121.784874,
- 88.35684,
- 61.32686,
- 41.302353,
- 27.215454,
- 17.638702,
- 11.284393,
- 7.144104,
- 4.4841614,
- 2.7943878,
- 1.7307587,
- 1.0663452,
+ 125,
+ 125,
+ 125,
+ 125,
+ 111.61491,
+ 86.9892,
+ 63.112034,
+ 43.8049,
+ 29.501678,
+ 19.439606,
+ 12.599068,
+ 8.06028,
+ 5.102936,
+ 3.2029724,
+ 1.9959946,
+ 1.2362518,
+ 0.761673,
0
]
}
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json
index 5cf66a4aa88c..7def82f08d0c 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json
@@ -13,12 +13,12 @@
"name": "Foo_yOffset",
"type": "float",
"data_points": [
- 175,
- 145.83333,
- 116.666664,
- 87.5,
- 58.33333,
- 29.166672,
+ 125,
+ 104.166664,
+ 83.33333,
+ 62.5,
+ 41.666664,
+ 20.833336,
0
]
}
diff --git a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeEnter.json b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeEnter.json
index 2df440912bfc..054b4a100dea 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeEnter.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeEnter.json
@@ -20,7 +20,7 @@
"height": 100
},
{
- "width": 125.14286,
+ "width": 125.2,
"height": 90
},
{
@@ -28,7 +28,7 @@
"height": 80
},
{
- "width": 175.14285,
+ "width": 175.2,
"height": 70
},
{
diff --git a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeExit.json b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeExit.json
index 2b0a9541a394..ad46a8d14ede 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeExit.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredSizeExit.json
@@ -21,7 +21,7 @@
"height": 100
},
{
- "width": 125.14286,
+ "width": 125.2,
"height": 90
},
{
@@ -29,7 +29,7 @@
"height": 80
},
{
- "width": 175.14285,
+ "width": 175.2,
"height": 70
},
{
diff --git a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredWidthOnly.json b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredWidthOnly.json
index 027df299d15e..9a97053eb821 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/testAnchoredWidthOnly.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/testAnchoredWidthOnly.json
@@ -20,7 +20,7 @@
"height": 60
},
{
- "width": 125.14286,
+ "width": 125.2,
"height": 60
},
{
@@ -28,7 +28,7 @@
"height": 60
},
{
- "width": 175.14285,
+ "width": 175.2,
"height": 60
},
{
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json
new file mode 100644
index 000000000000..0fcdfa3e1b53
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json
@@ -0,0 +1,634 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528,
+ 544,
+ 560,
+ 576,
+ 592,
+ 608,
+ 624,
+ 640,
+ 656,
+ 672,
+ 688,
+ 704,
+ 720,
+ 736,
+ 752,
+ 768,
+ 784,
+ 800,
+ 816,
+ 832,
+ 848,
+ 864,
+ 880,
+ 896,
+ 912,
+ 928,
+ 944,
+ 960
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50.4
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 52.4,
+ "y": 50
+ },
+ {
+ "x": 56,
+ "y": 50
+ },
+ {
+ "x": 58.8,
+ "y": 50
+ },
+ {
+ "x": 60.8,
+ "y": 50
+ },
+ {
+ "x": 62,
+ "y": 50
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 63.6,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 393.2
+ },
+ {
+ "width": 188,
+ "height": 393.2
+ },
+ {
+ "width": 188,
+ "height": 386
+ },
+ {
+ "width": 188,
+ "height": 379.6
+ },
+ {
+ "width": 188,
+ "height": 372.8
+ },
+ {
+ "width": 188,
+ "height": 366.8
+ },
+ {
+ "width": 188,
+ "height": 360.4
+ },
+ {
+ "width": 188,
+ "height": 354
+ },
+ {
+ "width": 188,
+ "height": 347.6
+ },
+ {
+ "width": 188,
+ "height": 341.2
+ },
+ {
+ "width": 188,
+ "height": 341.2
+ },
+ {
+ "width": 188,
+ "height": 334
+ },
+ {
+ "width": 188,
+ "height": 328
+ },
+ {
+ "width": 188,
+ "height": 321.6
+ },
+ {
+ "width": 188,
+ "height": 315.2
+ },
+ {
+ "width": 188,
+ "height": 308.8
+ },
+ {
+ "width": 188,
+ "height": 302.4
+ },
+ {
+ "width": 188,
+ "height": 296
+ },
+ {
+ "width": 188,
+ "height": 289.6
+ },
+ {
+ "width": 188,
+ "height": 289.6
+ },
+ {
+ "width": 188,
+ "height": 282.8
+ },
+ {
+ "width": 188,
+ "height": 276.4
+ },
+ {
+ "width": 188,
+ "height": 270
+ },
+ {
+ "width": 188,
+ "height": 263.6
+ },
+ {
+ "width": 188,
+ "height": 257.2
+ },
+ {
+ "width": 188,
+ "height": 250.8
+ },
+ {
+ "width": 188,
+ "height": 244.4
+ },
+ {
+ "width": 188,
+ "height": 238
+ },
+ {
+ "width": 188,
+ "height": 238
+ },
+ {
+ "width": 188,
+ "height": 231.2
+ },
+ {
+ "width": 188,
+ "height": 224.8
+ },
+ {
+ "width": 188,
+ "height": 218.4
+ },
+ {
+ "width": 188,
+ "height": 212
+ },
+ {
+ "width": 188,
+ "height": 212
+ },
+ {
+ "width": 188,
+ "height": 192.4
+ },
+ {
+ "width": 188,
+ "height": 159.6
+ },
+ {
+ "width": 188,
+ "height": 124.4
+ },
+ {
+ "width": 188,
+ "height": 92.8
+ },
+ {
+ "width": 183.2,
+ "height": 66.4
+ },
+ {
+ "width": 176,
+ "height": 46
+ },
+ {
+ "width": 170.4,
+ "height": 39.2
+ },
+ {
+ "width": 166.8,
+ "height": 36
+ },
+ {
+ "width": 164,
+ "height": 31.6
+ },
+ {
+ "width": 162.4,
+ "height": 26.8
+ },
+ {
+ "width": 161.2,
+ "height": 22
+ },
+ {
+ "width": 160.4,
+ "height": 17.6
+ },
+ {
+ "width": 160,
+ "height": 14
+ },
+ {
+ "width": 160,
+ "height": 10.8
+ },
+ {
+ "width": 160,
+ "height": 8
+ },
+ {
+ "width": 160,
+ "height": 6
+ },
+ {
+ "width": 160,
+ "height": 4.4
+ },
+ {
+ "width": 160,
+ "height": 2.8
+ },
+ {
+ "width": 160,
+ "height": 2
+ },
+ {
+ "width": 160,
+ "height": 1.2
+ },
+ {
+ "width": 160,
+ "height": 0.8
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0
+ },
+ {
+ "width": 160,
+ "height": 0
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0.9808927,
+ 0.8211168,
+ 0.61845565,
+ 0.43834114,
+ 0.29850912,
+ 0.19755232,
+ 0.12793064,
+ 0.08142871,
+ 0.051099956,
+ 0.031684637,
+ 0.019442618,
+ 0.011821032,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json
new file mode 100644
index 000000000000..3196334c5314
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json
@@ -0,0 +1,624 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528,
+ 544,
+ 560,
+ 576,
+ 592,
+ 608,
+ 624,
+ 640,
+ 656,
+ 672,
+ 688,
+ 704,
+ 720,
+ 736,
+ 752,
+ 768,
+ 784,
+ 800,
+ 816,
+ 832,
+ 848,
+ 864,
+ 880,
+ 896,
+ 912,
+ 928,
+ 944
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50.8,
+ "y": 52
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 52.4,
+ "y": 50
+ },
+ {
+ "x": 55.6,
+ "y": 50
+ },
+ {
+ "x": 58.4,
+ "y": 50
+ },
+ {
+ "x": 60.4,
+ "y": 50
+ },
+ {
+ "x": 61.6,
+ "y": 50
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 63.2,
+ "y": 50
+ },
+ {
+ "x": 63.6,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 390
+ },
+ {
+ "width": 188,
+ "height": 390
+ },
+ {
+ "width": 188,
+ "height": 379.2
+ },
+ {
+ "width": 188,
+ "height": 371.2
+ },
+ {
+ "width": 188,
+ "height": 363.2
+ },
+ {
+ "width": 188,
+ "height": 355.2
+ },
+ {
+ "width": 188,
+ "height": 347.2
+ },
+ {
+ "width": 188,
+ "height": 339.2
+ },
+ {
+ "width": 188,
+ "height": 331.2
+ },
+ {
+ "width": 188,
+ "height": 323.2
+ },
+ {
+ "width": 188,
+ "height": 323.2
+ },
+ {
+ "width": 188,
+ "height": 314.8
+ },
+ {
+ "width": 188,
+ "height": 306.8
+ },
+ {
+ "width": 188,
+ "height": 298.8
+ },
+ {
+ "width": 188,
+ "height": 290.8
+ },
+ {
+ "width": 188,
+ "height": 282.8
+ },
+ {
+ "width": 188,
+ "height": 274.8
+ },
+ {
+ "width": 188,
+ "height": 266.8
+ },
+ {
+ "width": 188,
+ "height": 258.8
+ },
+ {
+ "width": 188,
+ "height": 258.8
+ },
+ {
+ "width": 188,
+ "height": 250.4
+ },
+ {
+ "width": 188,
+ "height": 242.4
+ },
+ {
+ "width": 188,
+ "height": 234.4
+ },
+ {
+ "width": 188,
+ "height": 226.4
+ },
+ {
+ "width": 188,
+ "height": 218.4
+ },
+ {
+ "width": 188,
+ "height": 210.4
+ },
+ {
+ "width": 188,
+ "height": 202.4
+ },
+ {
+ "width": 188,
+ "height": 194.4
+ },
+ {
+ "width": 188,
+ "height": 194.4
+ },
+ {
+ "width": 188,
+ "height": 185.6
+ },
+ {
+ "width": 188,
+ "height": 178
+ },
+ {
+ "width": 188,
+ "height": 170
+ },
+ {
+ "width": 188,
+ "height": 161.6
+ },
+ {
+ "width": 188,
+ "height": 161.6
+ },
+ {
+ "width": 188,
+ "height": 144.8
+ },
+ {
+ "width": 188,
+ "height": 118.8
+ },
+ {
+ "width": 188,
+ "height": 92
+ },
+ {
+ "width": 183.6,
+ "height": 68
+ },
+ {
+ "width": 176.8,
+ "height": 48.4
+ },
+ {
+ "width": 171.6,
+ "height": 39.6
+ },
+ {
+ "width": 167.6,
+ "height": 36.8
+ },
+ {
+ "width": 164.8,
+ "height": 32.4
+ },
+ {
+ "width": 162.8,
+ "height": 27.6
+ },
+ {
+ "width": 161.6,
+ "height": 22.8
+ },
+ {
+ "width": 160.8,
+ "height": 18.4
+ },
+ {
+ "width": 160.4,
+ "height": 14.4
+ },
+ {
+ "width": 160,
+ "height": 11.2
+ },
+ {
+ "width": 160,
+ "height": 8.4
+ },
+ {
+ "width": 160,
+ "height": 6.4
+ },
+ {
+ "width": 160,
+ "height": 4.4
+ },
+ {
+ "width": 160,
+ "height": 3.2
+ },
+ {
+ "width": 160,
+ "height": 2
+ },
+ {
+ "width": 160,
+ "height": 1.6
+ },
+ {
+ "width": 160,
+ "height": 0.8
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0.9967737,
+ 0.86538374,
+ 0.66414475,
+ 0.47619528,
+ 0.32686388,
+ 0.21757984,
+ 0.14153665,
+ 0.09041709,
+ 0.05691254,
+ 0.035380244,
+ 0.02175957,
+ 0.01325649,
+ 0.008007765,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json
new file mode 100644
index 000000000000..4b0306853903
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json
@@ -0,0 +1,544 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528,
+ 544,
+ 560,
+ 576,
+ 592,
+ 608,
+ 624,
+ 640,
+ 656,
+ 672,
+ 688,
+ 704,
+ 720,
+ 736,
+ 752,
+ 768,
+ 784,
+ 800,
+ 816
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 61.6,
+ "y": 50
+ },
+ {
+ "x": 60.8,
+ "y": 50
+ },
+ {
+ "x": 59.6,
+ "y": 50
+ },
+ {
+ "x": 58.4,
+ "y": 50
+ },
+ {
+ "x": 57.2,
+ "y": 50
+ },
+ {
+ "x": 56,
+ "y": 50
+ },
+ {
+ "x": 55.2,
+ "y": 50
+ },
+ {
+ "x": 54,
+ "y": 50
+ },
+ {
+ "x": 54,
+ "y": 50
+ },
+ {
+ "x": 52.8,
+ "y": 50
+ },
+ {
+ "x": 51.6,
+ "y": 50
+ },
+ {
+ "x": 50.4,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "width": 162.4,
+ "height": 1.6
+ },
+ {
+ "width": 162.4,
+ "height": 1.6
+ },
+ {
+ "width": 164.8,
+ "height": 3.2
+ },
+ {
+ "width": 166.8,
+ "height": 4.8
+ },
+ {
+ "width": 169.2,
+ "height": 6.4
+ },
+ {
+ "width": 171.6,
+ "height": 8
+ },
+ {
+ "width": 173.6,
+ "height": 9.6
+ },
+ {
+ "width": 176,
+ "height": 11.2
+ },
+ {
+ "width": 178,
+ "height": 12.8
+ },
+ {
+ "width": 180.4,
+ "height": 14.4
+ },
+ {
+ "width": 180.4,
+ "height": 14.4
+ },
+ {
+ "width": 182.8,
+ "height": 16.4
+ },
+ {
+ "width": 185.2,
+ "height": 18
+ },
+ {
+ "width": 187.2,
+ "height": 19.6
+ },
+ {
+ "width": 188,
+ "height": 24.8
+ },
+ {
+ "width": 188,
+ "height": 32.8
+ },
+ {
+ "width": 188,
+ "height": 44
+ },
+ {
+ "width": 188,
+ "height": 57.2
+ },
+ {
+ "width": 188,
+ "height": 70.8
+ },
+ {
+ "width": 188,
+ "height": 78
+ },
+ {
+ "width": 188,
+ "height": 91.2
+ },
+ {
+ "width": 188,
+ "height": 103.2
+ },
+ {
+ "width": 188,
+ "height": 114.4
+ },
+ {
+ "width": 188,
+ "height": 124.4
+ },
+ {
+ "width": 188,
+ "height": 134
+ },
+ {
+ "width": 188,
+ "height": 142.8
+ },
+ {
+ "width": 188,
+ "height": 150.8
+ },
+ {
+ "width": 188,
+ "height": 158.8
+ },
+ {
+ "width": 188,
+ "height": 159.6
+ },
+ {
+ "width": 188,
+ "height": 167.2
+ },
+ {
+ "width": 188,
+ "height": 174
+ },
+ {
+ "width": 188,
+ "height": 180.8
+ },
+ {
+ "width": 188,
+ "height": 187.6
+ },
+ {
+ "width": 188,
+ "height": 187.6
+ },
+ {
+ "width": 188,
+ "height": 207.2
+ },
+ {
+ "width": 188,
+ "height": 240
+ },
+ {
+ "width": 188,
+ "height": 275.2
+ },
+ {
+ "width": 188,
+ "height": 306.8
+ },
+ {
+ "width": 188,
+ "height": 333.2
+ },
+ {
+ "width": 188,
+ "height": 353.6
+ },
+ {
+ "width": 188,
+ "height": 368.8
+ },
+ {
+ "width": 188,
+ "height": 380
+ },
+ {
+ "width": 188,
+ "height": 387.6
+ },
+ {
+ "width": 188,
+ "height": 392.4
+ },
+ {
+ "width": 188,
+ "height": 395.6
+ },
+ {
+ "width": 188,
+ "height": 398
+ },
+ {
+ "width": 188,
+ "height": 398.8
+ },
+ {
+ "width": 188,
+ "height": 399.6
+ },
+ {
+ "width": 188,
+ "height": 400
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0.0067873597,
+ 0.0612576,
+ 0.19080025,
+ 0.39327443,
+ 0.5711931,
+ 0.70855826,
+ 0.8074064,
+ 0.8754226,
+ 0.9207788,
+ 0.95032376,
+ 0.9692185,
+ 0.98112255,
+ 0.9885286,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json
new file mode 100644
index 000000000000..10a9ba7e2760
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json
@@ -0,0 +1,424 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528,
+ 544,
+ 560,
+ 576,
+ 592,
+ 608,
+ 624
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50.4,
+ "y": 50.8
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 51.2,
+ "y": 50
+ },
+ {
+ "x": 55.6,
+ "y": 50
+ },
+ {
+ "x": 58.8,
+ "y": 50
+ },
+ {
+ "x": 60.8,
+ "y": 50
+ },
+ {
+ "x": 62,
+ "y": 50
+ },
+ {
+ "x": 63.2,
+ "y": 50
+ },
+ {
+ "x": 63.6,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 389.6
+ },
+ {
+ "width": 188,
+ "height": 378.8
+ },
+ {
+ "width": 188,
+ "height": 366
+ },
+ {
+ "width": 188,
+ "height": 352
+ },
+ {
+ "width": 188,
+ "height": 352
+ },
+ {
+ "width": 188,
+ "height": 316.8
+ },
+ {
+ "width": 188,
+ "height": 261.2
+ },
+ {
+ "width": 188,
+ "height": 202.8
+ },
+ {
+ "width": 188,
+ "height": 150.8
+ },
+ {
+ "width": 188,
+ "height": 107.6
+ },
+ {
+ "width": 186,
+ "height": 74.4
+ },
+ {
+ "width": 177.2,
+ "height": 49.6
+ },
+ {
+ "width": 170.8,
+ "height": 39.6
+ },
+ {
+ "width": 166.8,
+ "height": 36.8
+ },
+ {
+ "width": 164,
+ "height": 32.4
+ },
+ {
+ "width": 162,
+ "height": 27.6
+ },
+ {
+ "width": 160.8,
+ "height": 22.8
+ },
+ {
+ "width": 160.4,
+ "height": 18.4
+ },
+ {
+ "width": 160,
+ "height": 14.4
+ },
+ {
+ "width": 160,
+ "height": 11.2
+ },
+ {
+ "width": 160,
+ "height": 8.4
+ },
+ {
+ "width": 160,
+ "height": 6
+ },
+ {
+ "width": 160,
+ "height": 4.4
+ },
+ {
+ "width": 160,
+ "height": 3.2
+ },
+ {
+ "width": 160,
+ "height": 2
+ },
+ {
+ "width": 160,
+ "height": 1.2
+ },
+ {
+ "width": 160,
+ "height": 0.8
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0
+ },
+ {
+ "width": 160,
+ "height": 0
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0.9833227,
+ 0.8263634,
+ 0.623688,
+ 0.44261706,
+ 0.3016883,
+ 0.1997872,
+ 0.12944388,
+ 0.08242595,
+ 0.051743627,
+ 0.032093227,
+ 0.019698441,
+ 0.0119793415,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json
new file mode 100644
index 000000000000..d8bf48d32d20
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json
@@ -0,0 +1,364 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "x": 62.4,
+ "y": 50
+ },
+ {
+ "x": 61.2,
+ "y": 50
+ },
+ {
+ "x": 59.2,
+ "y": 50
+ },
+ {
+ "x": 57.2,
+ "y": 50
+ },
+ {
+ "x": 54.8,
+ "y": 50
+ },
+ {
+ "x": 52.4,
+ "y": 50
+ },
+ {
+ "x": 52.4,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "width": 163.2,
+ "height": 2
+ },
+ {
+ "width": 166,
+ "height": 4.4
+ },
+ {
+ "width": 170,
+ "height": 6.8
+ },
+ {
+ "width": 174,
+ "height": 10
+ },
+ {
+ "width": 178.4,
+ "height": 13.2
+ },
+ {
+ "width": 183.6,
+ "height": 16.8
+ },
+ {
+ "width": 183.6,
+ "height": 16.8
+ },
+ {
+ "width": 188,
+ "height": 42.4
+ },
+ {
+ "width": 188,
+ "height": 100
+ },
+ {
+ "width": 188,
+ "height": 161.6
+ },
+ {
+ "width": 188,
+ "height": 218
+ },
+ {
+ "width": 188,
+ "height": 265.6
+ },
+ {
+ "width": 188,
+ "height": 303.6
+ },
+ {
+ "width": 188,
+ "height": 332.4
+ },
+ {
+ "width": 188,
+ "height": 354
+ },
+ {
+ "width": 188,
+ "height": 369.2
+ },
+ {
+ "width": 188,
+ "height": 380
+ },
+ {
+ "width": 188,
+ "height": 387.2
+ },
+ {
+ "width": 188,
+ "height": 392
+ },
+ {
+ "width": 188,
+ "height": 395.2
+ },
+ {
+ "width": 188,
+ "height": 397.6
+ },
+ {
+ "width": 188,
+ "height": 398.4
+ },
+ {
+ "width": 188,
+ "height": 398.8
+ },
+ {
+ "width": 188,
+ "height": 399.2
+ },
+ {
+ "width": 188,
+ "height": 399.6
+ },
+ {
+ "width": 188,
+ "height": 399.6
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ 0,
+ 0,
+ 0.008216977,
+ 0.06259775,
+ 0.19032806,
+ 0.39281356,
+ 0.57081985,
+ 0.7082821,
+ 0.80721295,
+ 0.8752918,
+ 0.9206928,
+ 0.95026827,
+ 0.9691833,
+ 0.98110056,
+ 0.988515,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json
new file mode 100644
index 000000000000..57bdf3e1ecab
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json
@@ -0,0 +1,744 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432,
+ 448,
+ 464,
+ 480,
+ 496,
+ 512,
+ 528,
+ 544,
+ 560,
+ 576,
+ 592,
+ 608,
+ 624,
+ 640,
+ 656,
+ 672,
+ 688,
+ 704,
+ 720,
+ 736,
+ 752,
+ 768,
+ 784,
+ 800,
+ 816,
+ 832,
+ 848,
+ 864,
+ 880,
+ 896,
+ 912,
+ 928,
+ 944,
+ 960,
+ 976,
+ 992,
+ 1008,
+ 1024,
+ 1040,
+ 1056,
+ 1072,
+ 1088,
+ 1104,
+ 1120,
+ 1136
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 62,
+ "y": 50
+ },
+ {
+ "x": 61.2,
+ "y": 50
+ },
+ {
+ "x": 60.4,
+ "y": 50
+ },
+ {
+ "x": 59.6,
+ "y": 50
+ },
+ {
+ "x": 58.8,
+ "y": 50
+ },
+ {
+ "x": 58,
+ "y": 50
+ },
+ {
+ "x": 57.2,
+ "y": 50
+ },
+ {
+ "x": 56.4,
+ "y": 50
+ },
+ {
+ "x": 55.6,
+ "y": 50
+ },
+ {
+ "x": 55.2,
+ "y": 50
+ },
+ {
+ "x": 54.4,
+ "y": 50
+ },
+ {
+ "x": 53.6,
+ "y": 50
+ },
+ {
+ "x": 53.2,
+ "y": 50
+ },
+ {
+ "x": 52.8,
+ "y": 50
+ },
+ {
+ "x": 52,
+ "y": 50
+ },
+ {
+ "x": 51.6,
+ "y": 50
+ },
+ {
+ "x": 51.2,
+ "y": 50
+ },
+ {
+ "x": 50.8,
+ "y": 50
+ },
+ {
+ "x": 50.4,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50.4,
+ "y": 50
+ },
+ {
+ "x": 50.8,
+ "y": 50
+ },
+ {
+ "x": 51.2,
+ "y": 50
+ },
+ {
+ "x": 51.6,
+ "y": 50
+ },
+ {
+ "x": 52,
+ "y": 50
+ },
+ {
+ "x": 52.8,
+ "y": 50
+ },
+ {
+ "x": 53.2,
+ "y": 50
+ },
+ {
+ "x": 53.6,
+ "y": 50
+ },
+ {
+ "x": 54.4,
+ "y": 50
+ },
+ {
+ "x": 55.2,
+ "y": 50
+ },
+ {
+ "x": 55.6,
+ "y": 50
+ },
+ {
+ "x": 56.4,
+ "y": 50
+ },
+ {
+ "x": 57.2,
+ "y": 50
+ },
+ {
+ "x": 58,
+ "y": 50
+ },
+ {
+ "x": 58.8,
+ "y": 50
+ },
+ {
+ "x": 59.6,
+ "y": 50
+ },
+ {
+ "x": 60.4,
+ "y": 50
+ },
+ {
+ "x": 61.2,
+ "y": 50
+ },
+ {
+ "x": 62,
+ "y": 50
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 63.6,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "width": 162.4,
+ "height": 1.6
+ },
+ {
+ "width": 164,
+ "height": 2.8
+ },
+ {
+ "width": 166,
+ "height": 4
+ },
+ {
+ "width": 167.6,
+ "height": 5.2
+ },
+ {
+ "width": 169.2,
+ "height": 6.4
+ },
+ {
+ "width": 170.8,
+ "height": 7.6
+ },
+ {
+ "width": 172.4,
+ "height": 8.8
+ },
+ {
+ "width": 174,
+ "height": 10
+ },
+ {
+ "width": 175.2,
+ "height": 10.8
+ },
+ {
+ "width": 176.8,
+ "height": 12
+ },
+ {
+ "width": 178,
+ "height": 12.8
+ },
+ {
+ "width": 179.2,
+ "height": 13.6
+ },
+ {
+ "width": 180.8,
+ "height": 14.8
+ },
+ {
+ "width": 182,
+ "height": 15.6
+ },
+ {
+ "width": 182.8,
+ "height": 16.4
+ },
+ {
+ "width": 184,
+ "height": 17.2
+ },
+ {
+ "width": 184.8,
+ "height": 17.6
+ },
+ {
+ "width": 186,
+ "height": 18.4
+ },
+ {
+ "width": 186.8,
+ "height": 19.2
+ },
+ {
+ "width": 187.6,
+ "height": 19.6
+ },
+ {
+ "width": 188,
+ "height": 21.2
+ },
+ {
+ "width": 188,
+ "height": 24
+ },
+ {
+ "width": 188,
+ "height": 29.6
+ },
+ {
+ "width": 188,
+ "height": 37.2
+ },
+ {
+ "width": 188,
+ "height": 45.6
+ },
+ {
+ "width": 188,
+ "height": 53.6
+ },
+ {
+ "width": 188,
+ "height": 60.4
+ },
+ {
+ "width": 188,
+ "height": 66.4
+ },
+ {
+ "width": 188,
+ "height": 71.2
+ },
+ {
+ "width": 188,
+ "height": 75.2
+ },
+ {
+ "width": 188,
+ "height": 77.6
+ },
+ {
+ "width": 188,
+ "height": 79.6
+ },
+ {
+ "width": 188,
+ "height": 80.4
+ },
+ {
+ "width": 188,
+ "height": 80.8
+ },
+ {
+ "width": 188,
+ "height": 80.4
+ },
+ {
+ "width": 188,
+ "height": 79.2
+ },
+ {
+ "width": 187.6,
+ "height": 78
+ },
+ {
+ "width": 186.8,
+ "height": 76
+ },
+ {
+ "width": 186,
+ "height": 74
+ },
+ {
+ "width": 184.8,
+ "height": 71.6
+ },
+ {
+ "width": 184,
+ "height": 69.2
+ },
+ {
+ "width": 182.8,
+ "height": 66
+ },
+ {
+ "width": 182,
+ "height": 62.8
+ },
+ {
+ "width": 180.8,
+ "height": 59.2
+ },
+ {
+ "width": 179.2,
+ "height": 55.6
+ },
+ {
+ "width": 178,
+ "height": 52
+ },
+ {
+ "width": 176.8,
+ "height": 48
+ },
+ {
+ "width": 175.2,
+ "height": 44
+ },
+ {
+ "width": 174,
+ "height": 40
+ },
+ {
+ "width": 172.4,
+ "height": 39.2
+ },
+ {
+ "width": 170.8,
+ "height": 38.4
+ },
+ {
+ "width": 169.2,
+ "height": 34.8
+ },
+ {
+ "width": 167.6,
+ "height": 30
+ },
+ {
+ "width": 166,
+ "height": 25.2
+ },
+ {
+ "width": 164,
+ "height": 20.4
+ },
+ {
+ "width": 162.4,
+ "height": 16.4
+ },
+ {
+ "width": 160.8,
+ "height": 12.8
+ },
+ {
+ "width": 160,
+ "height": 9.6
+ },
+ {
+ "width": 160,
+ "height": 7.2
+ },
+ {
+ "width": 160,
+ "height": 5.2
+ },
+ {
+ "width": 160,
+ "height": 3.6
+ },
+ {
+ "width": 160,
+ "height": 2.8
+ },
+ {
+ "width": 160,
+ "height": 1.6
+ },
+ {
+ "width": 160,
+ "height": 1.2
+ },
+ {
+ "width": 160,
+ "height": 0.8
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0
+ },
+ {
+ "width": 160,
+ "height": 0
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0.012518823,
+ 0.0741024,
+ 0.2254293,
+ 0.42628878,
+ 0.5976641,
+ 0.7280312,
+ 0.82100236,
+ 0.8845844,
+ 0.9267946,
+ 0.95419544,
+ 0.9716705,
+ 0.98265487,
+ 0.98947525,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0.9944124,
+ 0.9417388,
+ 0.8184184,
+ 0.6157812,
+ 0.4361611,
+ 0.2968906,
+ 0.19641554,
+ 0.12716137,
+ 0.080921985,
+ 0.050773025,
+ 0.03147719,
+ 0.019312752,
+ 0.011740655,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json
new file mode 100644
index 000000000000..9aa91c2d5e17
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json
@@ -0,0 +1,304 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ 400,
+ 416,
+ 432
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 53.2,
+ "y": 50
+ },
+ {
+ "x": 57.2,
+ "y": 50
+ },
+ {
+ "x": 59.6,
+ "y": 50
+ },
+ {
+ "x": 61.6,
+ "y": 50
+ },
+ {
+ "x": 62.8,
+ "y": 50
+ },
+ {
+ "x": 63.6,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 64,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 400
+ },
+ {
+ "width": 188,
+ "height": 372
+ },
+ {
+ "width": 188,
+ "height": 312.8
+ },
+ {
+ "width": 188,
+ "height": 246.8
+ },
+ {
+ "width": 188,
+ "height": 185.2
+ },
+ {
+ "width": 188,
+ "height": 133.6
+ },
+ {
+ "width": 188,
+ "height": 93.2
+ },
+ {
+ "width": 181.6,
+ "height": 62.8
+ },
+ {
+ "width": 174,
+ "height": 40.8
+ },
+ {
+ "width": 168.8,
+ "height": 38.4
+ },
+ {
+ "width": 165.2,
+ "height": 34.8
+ },
+ {
+ "width": 162.8,
+ "height": 30
+ },
+ {
+ "width": 161.2,
+ "height": 25.2
+ },
+ {
+ "width": 160.4,
+ "height": 20.4
+ },
+ {
+ "width": 160,
+ "height": 16.4
+ },
+ {
+ "width": 160,
+ "height": 12.8
+ },
+ {
+ "width": 160,
+ "height": 9.6
+ },
+ {
+ "width": 160,
+ "height": 7.2
+ },
+ {
+ "width": 160,
+ "height": 5.2
+ },
+ {
+ "width": 160,
+ "height": 3.6
+ },
+ {
+ "width": 160,
+ "height": 2.8
+ },
+ {
+ "width": 160,
+ "height": 1.6
+ },
+ {
+ "width": 160,
+ "height": 1.2
+ },
+ {
+ "width": 160,
+ "height": 0.8
+ },
+ {
+ "width": 160,
+ "height": 0.4
+ },
+ {
+ "width": 160,
+ "height": 0
+ },
+ {
+ "width": 160,
+ "height": 0
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0.91758585,
+ 0.72435355,
+ 0.52812576,
+ 0.3665868,
+ 0.24600428,
+ 0.16102076,
+ 0.103373945,
+ 0.06533456,
+ 0.04075712,
+ 0.025142312,
+ 0.015358448,
+ 0.0092999935,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json
new file mode 100644
index 000000000000..622c29eebfb4
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json
@@ -0,0 +1,244 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336
+ ],
+ "features": [
+ {
+ "name": "RevealElement_position",
+ "type": "dpOffset",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "x": 64,
+ "y": 50
+ },
+ {
+ "x": 59.2,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ },
+ {
+ "x": 50,
+ "y": 50
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_size",
+ "type": "dpSize",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "width": 160,
+ "height": 0
+ },
+ {
+ "width": 169.6,
+ "height": 6.8
+ },
+ {
+ "width": 188,
+ "height": 26.8
+ },
+ {
+ "width": 188,
+ "height": 95.6
+ },
+ {
+ "width": 188,
+ "height": 163.2
+ },
+ {
+ "width": 188,
+ "height": 222
+ },
+ {
+ "width": 188,
+ "height": 269.6
+ },
+ {
+ "width": 188,
+ "height": 307.2
+ },
+ {
+ "width": 188,
+ "height": 335.2
+ },
+ {
+ "width": 188,
+ "height": 356
+ },
+ {
+ "width": 188,
+ "height": 370.4
+ },
+ {
+ "width": 188,
+ "height": 380.8
+ },
+ {
+ "width": 188,
+ "height": 387.6
+ },
+ {
+ "width": 188,
+ "height": 392.4
+ },
+ {
+ "width": 188,
+ "height": 395.2
+ },
+ {
+ "width": 188,
+ "height": 397.2
+ },
+ {
+ "width": 188,
+ "height": 398
+ },
+ {
+ "width": 188,
+ "height": 398.8
+ },
+ {
+ "width": 188,
+ "height": 399.2
+ },
+ {
+ "width": 188,
+ "height": 399.2
+ },
+ {
+ "width": 188,
+ "height": 399.6
+ }
+ ]
+ },
+ {
+ "name": "RevealElement_alpha",
+ "type": "float",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ 0,
+ 0.05698657,
+ 0.24197984,
+ 0.44158113,
+ 0.6097554,
+ 0.73685503,
+ 0.8271309,
+ 0.8886989,
+ 0.9294886,
+ 0.9559254,
+ 0.97276413,
+ 0.98333716,
+ 0.98989624,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt
index b9bd115782b7..9d403507252f 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt
@@ -70,7 +70,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import platform.test.motion.compose.ComposeRecordingSpec
import platform.test.motion.compose.MotionControl
-import platform.test.motion.compose.createComposeMotionTestRule
+import platform.test.motion.compose.createFixedConfigurationComposeMotionTestRule
import platform.test.motion.compose.recordMotion
import platform.test.motion.compose.runTest
import platform.test.motion.golden.DataPoint
@@ -86,7 +86,7 @@ class TransitionScopedMechanicsAdapterTest {
createGoldenPathManager("frameworks/base/packages/SystemUI/compose/scene/tests/goldens")
private val testScope = TestScope()
- @get:Rule val motionRule = createComposeMotionTestRule(goldenPaths, testScope)
+ @get:Rule val motionRule = createFixedConfigurationComposeMotionTestRule(goldenPaths, testScope)
private val composeRule = motionRule.toolkit.composeContentTestRule
@Test
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt
new file mode 100644
index 000000000000..f4e2328f16ab
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.compose.animation.scene.reveal
+
+import android.platform.test.annotations.MotionTest
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.TouchInjectionScope
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.swipe
+import androidx.compose.ui.test.swipeDown
+import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.test.swipeWithVelocity
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.FeatureCaptures.elementAlpha
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateForTests
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
+import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.featureOfElement
+import com.android.compose.animation.scene.transitions
+import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.edgeContainerExpansionBackground
+import kotlin.math.sin
+import kotlinx.coroutines.CoroutineScope
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.motion.compose.ComposeFeatureCaptures.dpSize
+import platform.test.motion.compose.ComposeFeatureCaptures.positionInRoot
+import platform.test.motion.compose.ComposeRecordingSpec
+import platform.test.motion.compose.MotionControl
+import platform.test.motion.compose.MotionControlScope
+import platform.test.motion.compose.createFixedConfigurationComposeMotionTestRule
+import platform.test.motion.compose.recordMotion
+import platform.test.motion.compose.runTest
+import platform.test.motion.testing.createGoldenPathManager
+
+@RunWith(AndroidJUnit4::class)
+@MotionTest
+class ContentRevealTest {
+
+ private val goldenPaths =
+ createGoldenPathManager("frameworks/base/packages/SystemUI/compose/scene/tests/goldens")
+
+ @get:Rule val motionRule = createFixedConfigurationComposeMotionTestRule(goldenPaths)
+
+ private val fakeHaptics = FakeHaptics()
+
+ @Test
+ fun verticalReveal_triggeredRevealOpenTransition() {
+ assertVerticalContainerRevealMotion(TriggeredRevealMotion(SceneClosed, SceneOpen))
+ }
+
+ @Test
+ fun verticalReveal_triggeredRevealCloseTransition() {
+ assertVerticalContainerRevealMotion(TriggeredRevealMotion(SceneOpen, SceneClosed))
+ }
+
+ @Test
+ fun verticalReveal_gesture_magneticDetachAndReattach() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneClosed) {
+ val gestureDurationMillis = 1000L
+ swipe(
+ curve = {
+ val progress = it / gestureDurationMillis.toFloat()
+ val y = sin(progress * Math.PI).toFloat() * 100.dp.toPx()
+ Offset(centerX, y)
+ },
+ gestureDurationMillis,
+ )
+ }
+ )
+ }
+
+ @Test
+ fun verticalReveal_gesture_dragOpen() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneClosed) {
+ swipeDown(endY = 200.dp.toPx(), durationMillis = 500)
+ }
+ )
+ }
+
+ @Test
+ fun verticalReveal_gesture_flingOpen() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneClosed) {
+ val end = Offset(centerX, 80.dp.toPx())
+ swipeWithVelocity(start = topCenter, end = end, endVelocity = FlingVelocity.toPx())
+ }
+ )
+ }
+
+ @Test
+ fun verticalReveal_gesture_dragFullyClose() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneOpen) {
+ swipeUp(200.dp.toPx(), 0.dp.toPx(), durationMillis = 500)
+ }
+ )
+ }
+
+ @Test
+ fun verticalReveal_gesture_dragHalfClose() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneOpen) {
+ swipeUp(350.dp.toPx(), 100.dp.toPx(), durationMillis = 500)
+ }
+ )
+ }
+
+ @Test
+ fun verticalReveal_gesture_flingClose() {
+ assertVerticalContainerRevealMotion(
+ GestureRevealMotion(SceneOpen) {
+ val start = Offset(centerX, 260.dp.toPx())
+ val end = Offset(centerX, 200.dp.toPx())
+ swipeWithVelocity(start, end, FlingVelocity.toPx())
+ }
+ )
+ }
+
+ private interface RevealMotion {
+ val startScene: SceneKey
+ }
+
+ private class TriggeredRevealMotion(
+ override val startScene: SceneKey,
+ val targetScene: SceneKey,
+ ) : RevealMotion
+
+ private class GestureRevealMotion(
+ override val startScene: SceneKey,
+ val gestureControl: TouchInjectionScope.() -> Unit,
+ ) : RevealMotion
+
+ private fun assertVerticalContainerRevealMotion(testInstructions: RevealMotion) =
+ motionRule.runTest {
+ val transitions = transitions {
+ from(SceneClosed, to = SceneOpen) {
+ verticalContainerReveal(RevealElement, MotionSpec, fakeHaptics)
+ }
+ }
+
+ val state =
+ toolkit.composeContentTestRule.runOnUiThread {
+ MutableSceneTransitionLayoutStateForTests(
+ testInstructions.startScene,
+ transitions,
+ )
+ }
+ lateinit var coroutineScope: CoroutineScope
+
+ val recordTransition: suspend MotionControlScope.() -> Unit = {
+ when (testInstructions) {
+ is TriggeredRevealMotion -> {
+ val transition =
+ toolkit.composeContentTestRule.runOnUiThread {
+ state.setTargetScene(
+ testInstructions.targetScene,
+ animationScope = coroutineScope,
+ )
+ }
+ checkNotNull(transition).second.join()
+ }
+
+ is GestureRevealMotion -> {
+ performTouchInputAsync(
+ onNodeWithTag("stl"),
+ testInstructions.gestureControl,
+ )
+ awaitCondition { !state.isTransitioning() }
+ }
+ }
+ }
+ val recordingSpec =
+ ComposeRecordingSpec(
+ recordBefore = false,
+ recordAfter = false,
+ motionControl = MotionControl(recording = recordTransition),
+ ) {
+ featureOfElement(RevealElement, positionInRoot)
+ featureOfElement(RevealElement, dpSize)
+ featureOfElement(RevealElement, elementAlpha)
+ }
+
+ val motion =
+ recordMotion(
+ content = {
+ coroutineScope = rememberCoroutineScope()
+ SceneTransitionLayoutForTesting(
+ state,
+ modifier =
+ Modifier.padding(50.dp)
+ .background(Color.Yellow)
+ .size(ContainerSize.width, ContainerSize.height + 200.dp)
+ .testTag("stl"),
+ ) {
+ scene(
+ SceneClosed,
+ mapOf(Swipe.Down to SceneOpen),
+ content = { ClosedContainer() },
+ )
+ scene(
+ SceneOpen,
+ mapOf(Swipe.Up to SceneClosed),
+ content = { OpenContainer() },
+ )
+ }
+ },
+ recordingSpec,
+ )
+
+ assertThat(motion).timeSeriesMatchesGolden()
+ }
+
+ @Composable
+ fun ContentScope.ClosedContainer() {
+ Box(modifier = Modifier.fillMaxSize())
+ }
+
+ @Composable
+ fun ContentScope.OpenContainer() {
+ Box(contentAlignment = Alignment.TopCenter, modifier = Modifier.fillMaxSize()) {
+ Box(
+ modifier =
+ Modifier.element(RevealElement)
+ .size(ContainerSize)
+ .edgeContainerExpansionBackground(Color.DarkGray, MotionSpec)
+ )
+ }
+ }
+
+ private class FakeHaptics : ContainerRevealHaptics {
+ override fun onRevealThresholdCrossed(revealed: Boolean) {}
+ }
+
+ companion object {
+ val ContainerSize = DpSize(200.dp, 400.dp)
+
+ val FlingVelocity = 1000.dp // dp/sec
+
+ val SceneClosed = SceneKey("SceneA")
+ val SceneOpen = SceneKey("SceneB")
+
+ val RevealElement = ElementKey("RevealElement")
+ val MotionSpec = EdgeContainerExpansionSpec()
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
index 0bd51cd9822d..44f2353dcb75 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
@@ -111,8 +111,8 @@ private constructor(metadata: FailureMetadata, private val actual: TransitionSta
}
companion object {
- fun transitionStates() = Factory { metadata, actual: TransitionState ->
- TransitionStateSubject(metadata, actual)
+ fun transitionStates() = Factory { metadata, actual: TransitionState? ->
+ TransitionStateSubject(metadata, actual!!)
}
}
}
@@ -181,8 +181,8 @@ private constructor(metadata: FailureMetadata, actual: TransitionState.Transitio
companion object {
fun sceneTransitions() =
- Factory { metadata, actual: TransitionState.Transition.ChangeScene ->
- SceneTransitionSubject(metadata, actual)
+ Factory { metadata, actual: TransitionState.Transition.ChangeScene? ->
+ SceneTransitionSubject(metadata, actual!!)
}
}
}
@@ -202,8 +202,8 @@ private constructor(
companion object {
fun showOrHideOverlayTransitions() =
- Factory { metadata, actual: TransitionState.Transition.ShowOrHideOverlay ->
- ShowOrHideOverlayTransitionSubject(metadata, actual)
+ Factory { metadata, actual: TransitionState.Transition.ShowOrHideOverlay? ->
+ ShowOrHideOverlayTransitionSubject(metadata, actual!!)
}
}
}
@@ -221,8 +221,8 @@ private constructor(metadata: FailureMetadata, actual: TransitionState.Transitio
companion object {
fun replaceOverlayTransitions() =
- Factory { metadata, actual: TransitionState.Transition.ReplaceOverlay ->
- ReplaceOverlayTransitionSubject(metadata, actual)
+ Factory { metadata, actual: TransitionState.Transition.ReplaceOverlay? ->
+ ReplaceOverlayTransitionSubject(metadata, actual!!)
}
}
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredSizeTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredSizeTest.kt
index ea6f208d6bb9..3b008ac4c1df 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredSizeTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredSizeTest.kt
@@ -31,27 +31,21 @@ import com.android.compose.animation.scene.TransitionBuilder
import com.android.compose.animation.scene.TransitionRecordingSpec
import com.android.compose.animation.scene.featureOfElement
import com.android.compose.animation.scene.recordTransition
-import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.motion.compose.ComposeFeatureCaptures
-import platform.test.motion.compose.createComposeMotionTestRule
+import platform.test.motion.compose.createFixedConfigurationComposeMotionTestRule
import platform.test.motion.testing.createGoldenPathManager
-import platform.test.screenshot.ResetDeviceEmulationRule
@RunWith(AndroidJUnit4::class)
@MotionTest
class AnchoredSizeTest {
- companion object {
- @JvmField @ClassRule val cleanupRule: ResetDeviceEmulationRule = ResetDeviceEmulationRule()
- }
-
private val goldenPaths =
createGoldenPathManager("frameworks/base/packages/SystemUI/compose/scene/tests/goldens")
- @get:Rule val motionRule = createComposeMotionTestRule(goldenPaths)
+ @get:Rule val motionRule = createFixedConfigurationComposeMotionTestRule(goldenPaths)
@Test
fun testAnchoredSizeEnter() {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/subjects/DpOffsetSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/subjects/DpOffsetSubject.kt
index ab31038fac8f..368a333fbd78 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/subjects/DpOffsetSubject.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/subjects/DpOffsetSubject.kt
@@ -49,8 +49,8 @@ class DpOffsetSubject(metadata: FailureMetadata, private val actual: DpOffset) :
val DefaultTolerance = Dp(.5f)
fun dpOffsets() =
- Factory<DpOffsetSubject, DpOffset> { metadata, actual ->
- DpOffsetSubject(metadata, actual)
+ Factory { metadata, actual: DpOffset? ->
+ DpOffsetSubject(metadata, actual!!)
}
}
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
index e9e61a718f08..37acbe261f76 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
@@ -161,15 +161,7 @@ class ComposedDigitalLayerController(private val clockCtx: ClockContext) :
}
override fun onThemeChanged(theme: ThemeConfig) {
- val color =
- when {
- theme.seedColor != null -> theme.seedColor!!
- theme.isDarkTheme ->
- clockCtx.resources.getColor(android.R.color.system_accent1_100)
- else -> clockCtx.resources.getColor(android.R.color.system_accent2_600)
- }
-
- view.updateColor(color)
+ view.updateColor(theme.getDefaultColor(clockCtx.context))
}
override fun onFontSettingChanged(fontSizePx: Float) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 9bb3bac824e9..bc4bdf4243cb 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -17,7 +17,6 @@ import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Rect
-import android.graphics.RectF
import android.icu.text.NumberFormat
import android.util.TypedValue
import android.view.LayoutInflater
@@ -29,6 +28,7 @@ import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.ClockAnimations
import com.android.systemui.plugins.clocks.ClockConfig
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockEventListener
import com.android.systemui.plugins.clocks.ClockEvents
import com.android.systemui.plugins.clocks.ClockFaceConfig
import com.android.systemui.plugins.clocks.ClockFaceController
@@ -102,7 +102,7 @@ class DefaultClockController(
isDarkTheme: Boolean,
dozeFraction: Float,
foldFraction: Float,
- onBoundsChanged: (RectF) -> Unit,
+ clockListener: ClockEventListener?,
) {
largeClock.recomputePadding(null)
@@ -149,14 +149,7 @@ class DefaultClockController(
override fun onThemeChanged(theme: ThemeConfig) {
this@DefaultClockFaceController.theme = theme
- val color =
- when {
- theme.seedColor != null -> theme.seedColor!!
- theme.isDarkTheme ->
- resources.getColor(android.R.color.system_accent1_100)
- else -> resources.getColor(android.R.color.system_accent2_600)
- }
-
+ val color = theme.getDefaultColor(ctx)
if (currentColor == color) {
return
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
index 6dfd2268005f..5acd4468fe92 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
@@ -16,13 +16,13 @@
package com.android.systemui.shared.clocks
-import android.graphics.RectF
import com.android.systemui.animation.GSFAxes
import com.android.systemui.customization.R
import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.AxisType
import com.android.systemui.plugins.clocks.ClockConfig
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockEventListener
import com.android.systemui.plugins.clocks.ClockEvents
import com.android.systemui.plugins.clocks.ClockFontAxis
import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
@@ -107,11 +107,11 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController
isDarkTheme: Boolean,
dozeFraction: Float,
foldFraction: Float,
- onBoundsChanged: (RectF) -> Unit,
+ clockListener: ClockEventListener?,
) {
events.onFontAxesChanged(clockCtx.settings.axes)
smallClock.run {
- layerController.onViewBoundsChanged = onBoundsChanged
+ layerController.onViewBoundsChanged = { clockListener?.onBoundsChanged(it) }
events.onThemeChanged(theme.copy(isDarkTheme = isDarkTheme))
animations.doze(dozeFraction)
animations.fold(foldFraction)
@@ -119,7 +119,7 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController
}
largeClock.run {
- layerController.onViewBoundsChanged = onBoundsChanged
+ layerController.onViewBoundsChanged = { clockListener?.onBoundsChanged(it) }
events.onThemeChanged(theme.copy(isDarkTheme = isDarkTheme))
animations.doze(dozeFraction)
animations.fold(foldFraction)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
index 97004ef6f9a9..1d963af3ad22 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
@@ -229,15 +229,7 @@ open class SimpleDigitalHandLayerController(
}
override fun onThemeChanged(theme: ThemeConfig) {
- val color =
- when {
- theme.seedColor != null -> theme.seedColor!!
- theme.isDarkTheme ->
- clockCtx.resources.getColor(android.R.color.system_accent1_100)
- else -> clockCtx.resources.getColor(android.R.color.system_accent2_600)
- }
-
- view.updateColor(color)
+ view.updateColor(theme.getDefaultColor(clockCtx.context))
refreshTime()
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index fae17a5321ff..0ec2d188833a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -45,6 +45,7 @@ import com.android.systemui.plugins.clocks.ClockFontAxisSetting
import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.replace
import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.toFVar
import com.android.systemui.plugins.clocks.ClockLogger
+import com.android.systemui.shared.Flags.ambientAod
import com.android.systemui.shared.clocks.CanvasUtil.translate
import com.android.systemui.shared.clocks.CanvasUtil.use
import com.android.systemui.shared.clocks.ClockContext
@@ -330,7 +331,7 @@ open class SimpleDigitalClockTextView(
textAnimator.setTextStyle(
TextAnimator.Style(
fVar = if (isDozing) aodFontVariation else lsFontVariation,
- color = if (isDozing) AOD_COLOR else lockscreenColor,
+ color = if (isDozing && !ambientAod()) AOD_COLOR else lockscreenColor,
textSize = if (isDozing) aodFontSizePx else lockScreenPaint.textSize,
),
TextAnimator.Animation(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/KairosCoreStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/KairosCoreStartableTest.kt
new file mode 100644
index 000000000000..4daf02332d41
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/KairosCoreStartableTest.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kairos.toColdConflatedFlow
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.launch
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalKairosApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KairosCoreStartableTest : SysuiTestCase() {
+
+ @Test
+ fun kairosNetwork_usedBeforeStarted() =
+ testKosmos().useUnconfinedTestDispatcher().runKairosTest {
+ lateinit var activatable: TestActivatable
+ val underTest = KairosCoreStartable(applicationCoroutineScope) { setOf(activatable) }
+ activatable = TestActivatable(underTest)
+
+ // collect from the cold flow before starting the CoreStartable
+ var collectCount = 0
+ testScope.backgroundScope.launch { activatable.coldFlow.collect { collectCount++ } }
+
+ // start the CoreStartable
+ underTest.start()
+
+ // verify emissions are received
+ activatable.emitEvent()
+
+ assertThat(collectCount).isEqualTo(1)
+ }
+
+ private class TestActivatable(network: KairosNetwork) : KairosBuilder by kairosBuilder() {
+ private val emitter = MutableSharedFlow<Unit>()
+ private val events = buildEvents { emitter.toEvents() }
+
+ val coldFlow = events.toColdConflatedFlow(network)
+
+ suspend fun emitEvent() = emitter.emit(Unit)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt
new file mode 100644
index 000000000000..239e02640908
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.clipboardoverlay
+
+import android.content.ClipData
+import android.content.ComponentName
+import android.content.Intent
+import android.net.Uri
+import android.text.SpannableString
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ActionIntentCreatorTest : SysuiTestCase() {
+ val creator = ActionIntentCreator()
+
+ @Test
+ fun test_getTextEditorIntent() {
+ val intent = creator.getTextEditorIntent(context)
+ assertEquals(ComponentName(context, EditTextActivity::class.java), intent.component)
+ assertFlags(intent, Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ }
+
+ @Test
+ fun test_getRemoteCopyIntent() {
+ context.getOrCreateTestableResources().addOverride(R.string.config_remoteCopyPackage, "")
+
+ val clipData = ClipData.newPlainText("Test", "Test Item")
+ var intent = creator.getRemoteCopyIntent(clipData, context)
+
+ assertEquals(null, intent.component)
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+ assertEquals(clipData, intent.clipData)
+
+ // Try again with a remote copy component
+ val fakeComponent =
+ ComponentName("com.android.remotecopy", "com.android.remotecopy.RemoteCopyActivity")
+ context
+ .getOrCreateTestableResources()
+ .addOverride(R.string.config_remoteCopyPackage, fakeComponent.flattenToString())
+
+ intent = creator.getRemoteCopyIntent(clipData, context)
+ assertEquals(fakeComponent, intent.component)
+ }
+
+ @Test
+ fun test_getImageEditIntent() {
+ context.getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor, "")
+ val fakeUri = Uri.parse("content://foo")
+ var intent = creator.getImageEditIntent(fakeUri, context)
+
+ assertEquals(Intent.ACTION_EDIT, intent.action)
+ assertEquals("image/*", intent.type)
+ assertEquals(null, intent.component)
+ assertEquals("clipboard", intent.getStringExtra("edit_source"))
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+
+ // try again with an editor component
+ val fakeComponent =
+ ComponentName("com.android.remotecopy", "com.android.remotecopy.RemoteCopyActivity")
+ context
+ .getOrCreateTestableResources()
+ .addOverride(R.string.config_screenshotEditor, fakeComponent.flattenToString())
+ intent = creator.getImageEditIntent(fakeUri, context)
+ assertEquals(fakeComponent, intent.component)
+ }
+
+ @Test
+ fun test_getShareIntent_plaintext() {
+ val clipData = ClipData.newPlainText("Test", "Test Item")
+ val intent = creator.getShareIntent(clipData, context)
+
+ assertEquals(Intent.ACTION_CHOOSER, intent.action)
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+ val target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
+ assertEquals("Test Item", target?.getStringExtra(Intent.EXTRA_TEXT))
+ assertEquals("text/plain", target?.type)
+ }
+
+ @Test
+ fun test_getShareIntent_html() {
+ val clipData = ClipData.newHtmlText("Test", "Some HTML", "<b>Some HTML</b>")
+ val intent = creator.getShareIntent(clipData, getContext())
+
+ assertEquals(Intent.ACTION_CHOOSER, intent.action)
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+ val target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
+ assertEquals("Some HTML", target?.getStringExtra(Intent.EXTRA_TEXT))
+ assertEquals("text/plain", target?.type)
+ }
+
+ @Test
+ fun test_getShareIntent_image() {
+ val uri = Uri.parse("content://something")
+ val clipData = ClipData("Test", arrayOf("image/png"), ClipData.Item(uri))
+ val intent = creator.getShareIntent(clipData, context)
+
+ assertEquals(Intent.ACTION_CHOOSER, intent.action)
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+ val target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
+ assertEquals(uri, target?.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))
+ assertEquals(uri, target?.clipData?.getItemAt(0)?.uri)
+ assertEquals("image/png", target?.type)
+ }
+
+ @Test
+ fun test_getShareIntent_spannableText() {
+ val clipData = ClipData.newPlainText("Test", SpannableString("Test Item"))
+ val intent = creator.getShareIntent(clipData, context)
+
+ assertEquals(Intent.ACTION_CHOOSER, intent.action)
+ assertFlags(intent, EXTERNAL_INTENT_FLAGS)
+ val target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
+ assertEquals("Test Item", target?.getStringExtra(Intent.EXTRA_TEXT))
+ assertEquals("text/plain", target?.type)
+ }
+
+ // Assert that the given flags are set
+ private fun assertFlags(intent: Intent, flags: Int) {
+ assertTrue((intent.flags and flags) == flags)
+ }
+
+ companion object {
+ private const val EXTERNAL_INTENT_FLAGS: Int =
+ (Intent.FLAG_ACTIVITY_NEW_TASK or
+ Intent.FLAG_ACTIVITY_CLEAR_TASK or
+ Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java
index ea6cb3b6d178..126b3fa9e7ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java
@@ -36,13 +36,15 @@ import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class IntentCreatorTest extends SysuiTestCase {
+public class DefaultIntentCreatorTest extends SysuiTestCase {
private static final int EXTERNAL_INTENT_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION;
+ private final DefaultIntentCreator mIntentCreator = new DefaultIntentCreator();
+
@Test
public void test_getTextEditorIntent() {
- Intent intent = IntentCreator.getTextEditorIntent(getContext());
+ Intent intent = mIntentCreator.getTextEditorIntent(getContext());
assertEquals(new ComponentName(getContext(), EditTextActivity.class),
intent.getComponent());
assertFlags(intent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
@@ -54,7 +56,7 @@ public class IntentCreatorTest extends SysuiTestCase {
"");
ClipData clipData = ClipData.newPlainText("Test", "Test Item");
- Intent intent = IntentCreator.getRemoteCopyIntent(clipData, getContext());
+ Intent intent = mIntentCreator.getRemoteCopyIntent(clipData, getContext());
assertEquals(null, intent.getComponent());
assertFlags(intent, EXTERNAL_INTENT_FLAGS);
@@ -66,7 +68,7 @@ public class IntentCreatorTest extends SysuiTestCase {
getContext().getOrCreateTestableResources().addOverride(R.string.config_remoteCopyPackage,
fakeComponent.flattenToString());
- intent = IntentCreator.getRemoteCopyIntent(clipData, getContext());
+ intent = mIntentCreator.getRemoteCopyIntent(clipData, getContext());
assertEquals(fakeComponent, intent.getComponent());
}
@@ -75,7 +77,7 @@ public class IntentCreatorTest extends SysuiTestCase {
getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
"");
Uri fakeUri = Uri.parse("content://foo");
- Intent intent = IntentCreator.getImageEditIntent(fakeUri, getContext());
+ Intent intent = mIntentCreator.getImageEditIntent(fakeUri, getContext());
assertEquals(Intent.ACTION_EDIT, intent.getAction());
assertEquals("image/*", intent.getType());
@@ -88,14 +90,14 @@ public class IntentCreatorTest extends SysuiTestCase {
"com.android.remotecopy.RemoteCopyActivity");
getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
fakeComponent.flattenToString());
- intent = IntentCreator.getImageEditIntent(fakeUri, getContext());
+ intent = mIntentCreator.getImageEditIntent(fakeUri, getContext());
assertEquals(fakeComponent, intent.getComponent());
}
@Test
public void test_getShareIntent_plaintext() {
ClipData clipData = ClipData.newPlainText("Test", "Test Item");
- Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+ Intent intent = mIntentCreator.getShareIntent(clipData, getContext());
assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
assertFlags(intent, EXTERNAL_INTENT_FLAGS);
@@ -108,7 +110,7 @@ public class IntentCreatorTest extends SysuiTestCase {
public void test_getShareIntent_html() {
ClipData clipData = ClipData.newHtmlText("Test", "Some HTML",
"<b>Some HTML</b>");
- Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+ Intent intent = mIntentCreator.getShareIntent(clipData, getContext());
assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
assertFlags(intent, EXTERNAL_INTENT_FLAGS);
@@ -122,7 +124,7 @@ public class IntentCreatorTest extends SysuiTestCase {
Uri uri = Uri.parse("content://something");
ClipData clipData = new ClipData("Test", new String[]{"image/png"},
new ClipData.Item(uri));
- Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+ Intent intent = mIntentCreator.getShareIntent(clipData, getContext());
assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
assertFlags(intent, EXTERNAL_INTENT_FLAGS);
@@ -135,7 +137,7 @@ public class IntentCreatorTest extends SysuiTestCase {
@Test
public void test_getShareIntent_spannableText() {
ClipData clipData = ClipData.newPlainText("Test", new SpannableString("Test Item"));
- Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+ Intent intent = mIntentCreator.getShareIntent(clipData, getContext());
assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
assertFlags(intent, EXTERNAL_INTENT_FLAGS);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt
index ed9cd98a825a..f64f13d4a9b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.common.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.model.StateChange
import com.android.systemui.model.fakeSysUIStatePerDisplayRepository
import com.android.systemui.model.sysUiStateFactory
@@ -26,6 +27,7 @@ import com.android.systemui.model.sysuiStateInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.runner.RunWith
@@ -49,6 +51,13 @@ class SysUIStatePerDisplayInteractorTest : SysuiTestCase() {
add(1, state1)
add(2, state2)
}
+ runBlocking {
+ kosmos.displayRepository.apply {
+ addDisplay(0)
+ addDisplay(1)
+ addDisplay(2)
+ }
+ }
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index f47aa6b3dc03..8dc7a331dc2d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -32,6 +32,8 @@ import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
+import com.android.systemui.common.data.repository.batteryRepository
+import com.android.systemui.common.data.repository.fake
import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
@@ -48,6 +50,7 @@ import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.interactor.communalTutorialInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.log.CommunalMetricsLogger
import com.android.systemui.communal.shared.model.CommunalContentSize
@@ -73,6 +76,8 @@ import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
@@ -96,6 +101,7 @@ import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.advanceTimeBy
@@ -940,6 +946,36 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(isUiBlurred).isFalse()
}
+ @Test
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+ fun swipeToCommunal() =
+ kosmos.runTest {
+ setCommunalV2ConfigEnabled(true)
+ val mainUser = fakeUserRepository.asMainUser()
+ fakeKeyguardRepository.setKeyguardShowing(true)
+ fakeUserRepository.setUserUnlocked(mainUser.id, true)
+ fakeUserTracker.set(userInfos = listOf(mainUser), selectedUserIndex = 0)
+ fakeSettings.putIntForUser(
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
+ 1,
+ mainUser.id,
+ )
+
+ val viewModel = createViewModel()
+ val swipeToHubEnabled by collectLastValue(viewModel.swipeToHubEnabled)
+ assertThat(swipeToHubEnabled).isFalse()
+
+ batteryRepository.fake.setDevicePluggedIn(true)
+ assertThat(swipeToHubEnabled).isTrue()
+
+ keyguardTransitionRepository.sendTransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.AOD,
+ transitionState = TransitionState.STARTED,
+ )
+ assertThat(swipeToHubEnabled).isFalse()
+ }
+
private suspend fun setIsMainUser(isMainUser: Boolean) {
val user = if (isMainUser) MAIN_USER_INFO else SECONDARY_USER_INFO
with(userRepository) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
index e0515000b232..454c15667f22 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
@@ -56,6 +56,7 @@ import com.android.systemui.statusbar.phone.dozeScrimController
import com.android.systemui.statusbar.phone.screenOffAnimationController
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
@@ -105,7 +106,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
@Test
fun nonPowerButtonFPS_vibrateSuccess() =
testScope.runTest {
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
runCurrent()
enterDeviceFromFingerprintUnlockLegacy()
@@ -116,7 +117,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
@Test
fun powerButtonFPS_vibrateSuccess() =
testScope.runTest {
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
kosmos.fakeKeyEventRepository.setPowerButtonDown(false)
@@ -133,7 +134,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
@Test
fun powerButtonFPS_powerDown_doNotVibrateSuccess() =
testScope.runTest {
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
kosmos.fakeKeyEventRepository.setPowerButtonDown(true) // power button is currently DOWN
@@ -150,7 +151,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
@Test
fun powerButtonFPS_powerButtonRecentlyPressed_doNotVibrateSuccess() =
testScope.runTest {
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
kosmos.fakeKeyEventRepository.setPowerButtonDown(false)
@@ -174,14 +175,14 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
}
@Test
- fun nonPowerButtonFPS_coExFaceFailure_vibrateError() =
+ fun nonPowerButtonFPS_coExFaceFailure_doNotVibrateError() =
testScope.runTest {
val playErrorHaptic by collectLastValue(underTest.playErrorHaptic)
enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
enrollFace()
runCurrent()
faceFailure()
- assertThat(playErrorHaptic).isNotNull()
+ assertThat(playErrorHaptic).isNull()
}
@Test
@@ -211,7 +212,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
testScope.runTest {
kosmos.configureKeyguardBypass(isBypassAvailable = false)
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
runCurrent()
configureDeviceEntryFromBiometricSource(isFpUnlock = true)
@@ -225,7 +226,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
testScope.runTest {
kosmos.configureKeyguardBypass(isBypassAvailable = false)
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
kosmos.fakeKeyEventRepository.setPowerButtonDown(false)
@@ -246,18 +247,19 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
enrollFace()
kosmos.configureKeyguardBypass(isBypassAvailable = true)
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
configureDeviceEntryFromBiometricSource(isFaceUnlock = true)
verifyDeviceEntryFromFaceAuth()
assertThat(playSuccessHaptic).isNotNull()
}
+ @OptIn(ExperimentalCoroutinesApi::class)
@EnableSceneContainer
@Test
- fun playSuccessHaptic_onFaceAuthSuccess_whenBypassDisabled_sceneContainer() =
+ fun skipSuccessHaptic_onFaceAuthSuccess_whenBypassDisabled_sceneContainer() =
testScope.runTest {
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFace()
kosmos.configureKeyguardBypass(isBypassAvailable = false)
@@ -265,7 +267,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
configureDeviceEntryFromBiometricSource(isFaceUnlock = true, bypassEnabled = false)
kosmos.fakeDeviceEntryFaceAuthRepository.isAuthenticated.value = true
- assertThat(playSuccessHaptic).isNotNull()
+ assertThat(playSuccessHaptic).isNull()
}
@EnableSceneContainer
@@ -274,7 +276,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
testScope.runTest {
kosmos.configureKeyguardBypass(isBypassAvailable = false)
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
// power button is currently DOWN
kosmos.fakeKeyEventRepository.setPowerButtonDown(true)
@@ -295,7 +297,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
testScope.runTest {
kosmos.configureKeyguardBypass(isBypassAvailable = false)
underTest = kosmos.deviceEntryHapticsInteractor
- val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
+ val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
kosmos.fakeKeyEventRepository.setPowerButtonDown(false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
index 299105e2dabd..e41d46ce90af 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
@@ -20,6 +20,7 @@ import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.testKosmos
@@ -29,6 +30,9 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.verify
@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -99,6 +103,11 @@ class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() {
assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed).isEmpty()
}
+ @Test
+ fun start_registersDumpable() {
+ verify(kosmos.dumpManager).registerNormalDumpable(anyString(), eq(underTest))
+ }
+
private fun createDisplay(displayId: Int): Display =
display(type = Display.TYPE_INTERNAL, id = displayId)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/log/LogWtfHandlerRuleTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/LogWtfHandlerRuleTest.kt
new file mode 100644
index 000000000000..d5d256e5cd97
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/LogWtfHandlerRuleTest.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.log
+
+import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.model.Statement
+import org.mockito.kotlin.mock
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class LogWtfHandlerRuleTest : SysuiTestCase() {
+
+ val underTest = LogWtfHandlerRule()
+
+ @Test
+ fun passingTestWithoutWtf_shouldPass() {
+ val result = runTestCodeWithRule {
+ Log.e(TAG, "just an error", IndexOutOfBoundsException())
+ }
+ assertThat(result.isSuccess).isTrue()
+ }
+
+ @Test
+ fun passingTestWithWtf_shouldFail() {
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG, "some terrible failure", IllegalStateException())
+ }
+ assertThat(result.isFailure).isTrue()
+ val exception = result.exceptionOrNull()
+ assertThat(exception).isInstanceOf(AssertionError::class.java)
+ assertThat(exception?.cause).isInstanceOf(Log.TerribleFailure::class.java)
+ assertThat(exception?.cause?.cause).isInstanceOf(IllegalStateException::class.java)
+ }
+
+ @Test
+ fun failingTestWithoutWtf_shouldFail() {
+ val result = runTestCodeWithRule {
+ Log.e(TAG, "just an error", IndexOutOfBoundsException())
+ throw NullPointerException("some npe")
+ }
+ assertThat(result.isFailure).isTrue()
+ assertThat(result.exceptionOrNull()).isInstanceOf(NullPointerException::class.java)
+ }
+
+ @Test
+ fun failingTestWithWtf_shouldFail() {
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG, "some terrible failure", IllegalStateException())
+ throw NullPointerException("some npe")
+ }
+ assertThat(result.isFailure).isTrue()
+ assertThat(result.exceptionOrNull()).isInstanceOf(NullPointerException::class.java)
+ val suppressedExceptions = result.exceptionOrNull()!!.suppressedExceptions
+ assertThat(suppressedExceptions).hasSize(1)
+ val suppressed = suppressedExceptions.first()
+ assertThat(suppressed).isInstanceOf(AssertionError::class.java)
+ assertThat(suppressed.cause).isInstanceOf(Log.TerribleFailure::class.java)
+ assertThat(suppressed.cause?.cause).isInstanceOf(IllegalStateException::class.java)
+ }
+
+ @Test
+ fun passingTestWithExemptWtf_shouldPass() {
+ underTest.addFailureLogExemption { it.tag == TAG_EXPECTED }
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG_EXPECTED, "some expected failure", IllegalStateException())
+ }
+ assertThat(result.isSuccess).isTrue()
+ }
+
+ @Test
+ fun failingTestWithExemptWtf_shouldFail() {
+ underTest.addFailureLogExemption { it.tag == TAG_EXPECTED }
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG_EXPECTED, "some expected failure", IllegalStateException())
+ throw NullPointerException("some npe")
+ }
+ assertThat(result.isFailure).isTrue()
+ assertThat(result.exceptionOrNull()).isInstanceOf(NullPointerException::class.java)
+ val suppressedExceptions = result.exceptionOrNull()!!.suppressedExceptions
+ assertThat(suppressedExceptions).isEmpty()
+ }
+
+ @Test
+ fun passingTestWithOneExemptWtfOfTwo_shouldFail() {
+ underTest.addFailureLogExemption { it.tag == TAG_EXPECTED }
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG_EXPECTED, "some expected failure", IllegalStateException())
+ Log.wtf(TAG, "some terrible failure", IllegalStateException())
+ }
+ assertThat(result.isFailure).isTrue()
+ val exception = result.exceptionOrNull()
+ assertThat(exception).isInstanceOf(AssertionError::class.java)
+ assertThat(exception?.cause).isInstanceOf(Log.TerribleFailure::class.java)
+ assertThat(exception?.cause?.cause).isInstanceOf(IllegalStateException::class.java)
+ }
+
+ @Test
+ fun failingTestWithOneExemptWtfOfTwo_shouldFail() {
+ underTest.addFailureLogExemption { it.tag == TAG_EXPECTED }
+ val result = runTestCodeWithRule {
+ Log.wtf(TAG_EXPECTED, "some expected failure", IllegalStateException())
+ Log.wtf(TAG, "some terrible failure", IllegalStateException())
+ throw NullPointerException("some npe")
+ }
+ assertThat(result.isFailure).isTrue()
+ assertThat(result.exceptionOrNull()).isInstanceOf(NullPointerException::class.java)
+ val suppressedExceptions = result.exceptionOrNull()!!.suppressedExceptions
+ assertThat(suppressedExceptions).hasSize(1)
+ val suppressed = suppressedExceptions.first()
+ assertThat(suppressed).isInstanceOf(AssertionError::class.java)
+ assertThat(suppressed.cause).isInstanceOf(Log.TerribleFailure::class.java)
+ assertThat(suppressed.cause?.cause).isInstanceOf(IllegalStateException::class.java)
+ }
+
+ private fun runTestCodeWithRule(testCode: () -> Unit): Result<Unit> {
+ val testCodeStatement =
+ object : Statement() {
+ override fun evaluate() {
+ testCode()
+ }
+ }
+ val wrappedTest = underTest.apply(testCodeStatement, mock())
+ return try {
+ wrappedTest.evaluate()
+ Result.success(Unit)
+ } catch (e: Throwable) {
+ Result.failure(e)
+ }
+ }
+
+ companion object {
+ const val TAG = "LogWtfHandlerRuleTest"
+ const val TAG_EXPECTED = "EXPECTED"
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
index 0197a1e61801..c72afc72fa16 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
@@ -16,26 +16,17 @@
package com.android.systemui.media.controls.domain.interactor
-import android.R
-import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
-import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
-import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -52,16 +43,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
private val mediaFilterRepository: MediaFilterRepository =
with(kosmos) { mediaFilterRepository }
- private val mediaRecommendationsInteractor: MediaRecommendationsInteractor =
- kosmos.mediaRecommendationsInteractor
- val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
- private val mediaRecommendation =
- SmartspaceMediaData(
- targetId = KEY_MEDIA_SMARTSPACE,
- isActive = true,
- packageName = PACKAGE_NAME,
- recommendations = MediaTestHelper.getValidRecommendationList(icon),
- )
private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor
@@ -119,81 +100,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
}
@Test
- fun addActiveRecommendation_inactiveMedia() =
- testScope.runTest {
- val hasActiveMediaOrRecommendation by
- collectLastValue(underTest.hasActiveMediaOrRecommendation)
- val hasAnyMediaOrRecommendation by
- collectLastValue(underTest.hasAnyMediaOrRecommendation)
- val currentMedia by collectLastValue(underTest.currentMedia)
-
- val userMedia = MediaData(active = false)
- val recsLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
- val mediaLoadingModel = MediaDataLoadingModel.Loaded(userMedia.instanceId)
-
- mediaFilterRepository.setRecommendation(mediaRecommendation)
- mediaFilterRepository.setRecommendationsLoadingState(recsLoadingModel)
-
- assertThat(hasActiveMediaOrRecommendation).isTrue()
- assertThat(hasAnyMediaOrRecommendation).isTrue()
- assertThat(currentMedia)
- .containsExactly(MediaCommonModel.MediaRecommendations(recsLoadingModel))
-
- mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
- mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
- mediaFilterRepository.setOrderedMedia()
-
- assertThat(hasActiveMediaOrRecommendation).isTrue()
- assertThat(hasAnyMediaOrRecommendation).isTrue()
- assertThat(currentMedia)
- .containsExactly(
- MediaCommonModel.MediaRecommendations(recsLoadingModel),
- MediaCommonModel.MediaControl(mediaLoadingModel, true),
- )
- .inOrder()
- }
-
- @Test
- fun addActiveRecommendation_thenInactive() =
- testScope.runTest {
- val hasActiveMediaOrRecommendation by
- collectLastValue(underTest.hasActiveMediaOrRecommendation)
- val hasAnyMediaOrRecommendation by
- collectLastValue(underTest.hasAnyMediaOrRecommendation)
-
- mediaFilterRepository.setRecommendation(mediaRecommendation)
-
- assertThat(hasActiveMediaOrRecommendation).isTrue()
- assertThat(hasAnyMediaOrRecommendation).isTrue()
-
- mediaFilterRepository.setRecommendation(mediaRecommendation.copy(isActive = false))
-
- assertThat(hasActiveMediaOrRecommendation).isFalse()
- assertThat(hasAnyMediaOrRecommendation).isFalse()
- }
-
- @Test
- fun addActiveRecommendation_thenInvalid() =
- testScope.runTest {
- val hasActiveMediaOrRecommendation by
- collectLastValue(underTest.hasActiveMediaOrRecommendation)
- val hasAnyMediaOrRecommendation by
- collectLastValue(underTest.hasAnyMediaOrRecommendation)
-
- mediaFilterRepository.setRecommendation(mediaRecommendation)
-
- assertThat(hasActiveMediaOrRecommendation).isTrue()
- assertThat(hasAnyMediaOrRecommendation).isTrue()
-
- mediaFilterRepository.setRecommendation(
- mediaRecommendation.copy(recommendations = listOf())
- )
-
- assertThat(hasActiveMediaOrRecommendation).isFalse()
- assertThat(hasAnyMediaOrRecommendation).isFalse()
- }
-
- @Test
fun hasAnyMedia_noMediaSet_returnsFalse() =
testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() }
@@ -208,47 +114,4 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
@Test
fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() =
testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() }
-
- @Test
- fun loadMediaFromRec() =
- testScope.runTest {
- val currentMedia by collectLastValue(underTest.currentMedia)
- val instanceId = InstanceId.fakeInstanceId(123)
- val data =
- MediaData(
- active = true,
- instanceId = instanceId,
- packageName = PACKAGE_NAME,
- notificationKey = KEY,
- )
- val smartspaceLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
- val mediaLoadingModel = MediaDataLoadingModel.Loaded(instanceId)
-
- mediaFilterRepository.setRecommendation(mediaRecommendation)
- mediaFilterRepository.setRecommendationsLoadingState(smartspaceLoadingModel)
- mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME)
- mediaFilterRepository.addSelectedUserMediaEntry(data)
- mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
-
- assertThat(currentMedia)
- .containsExactly(MediaCommonModel.MediaRecommendations(smartspaceLoadingModel))
- .inOrder()
-
- mediaFilterRepository.addSelectedUserMediaEntry(data.copy(isPlaying = true))
- mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
-
- assertThat(currentMedia)
- .containsExactly(
- MediaCommonModel.MediaControl(mediaLoadingModel, isMediaFromRec = true),
- MediaCommonModel.MediaRecommendations(smartspaceLoadingModel),
- )
- .inOrder()
- }
-
- companion object {
- private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
- private const val PACKAGE_NAME = "com.android.example"
- private const val KEY = "key"
- private const val SURFACE = 4
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
deleted file mode 100644
index 2265c0149cc3..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.domain.interactor
-
-import android.R
-import android.content.ComponentName
-import android.content.Intent
-import android.content.applicationContext
-import android.graphics.drawable.Icon
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.Expandable
-import com.android.systemui.broadcast.broadcastSender
-import com.android.systemui.broadcast.mockBroadcastSender
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.MediaTestHelper
-import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
-import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
-import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor.Companion.EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
-import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
-import com.android.systemui.media.controls.shared.model.MediaRecModel
-import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
-import com.android.systemui.plugins.activityStarter
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.doNothing
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
-import org.mockito.kotlin.eq
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MediaRecommendationsInteractorTest : SysuiTestCase() {
-
- private val spyContext = spy(context)
- private val kosmos = testKosmos().apply { applicationContext = spyContext }
- private val testScope = kosmos.testScope
-
- private val mediaDataFilter: MediaDataFilterImpl = with(kosmos) { mediaDataFilter }
- private val activityStarter = kosmos.activityStarter
- private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
- private val smartspaceMediaData: SmartspaceMediaData =
- SmartspaceMediaData(
- targetId = KEY_MEDIA_SMARTSPACE,
- isActive = true,
- packageName = PACKAGE_NAME,
- recommendations = MediaTestHelper.getValidRecommendationList(icon),
- )
-
- private val underTest: MediaRecommendationsInteractor =
- with(kosmos) {
- broadcastSender = mockBroadcastSender
- kosmos.mediaRecommendationsInteractor
- }
-
- @Test
- fun addRecommendation_smartspaceMediaDataUpdate() =
- testScope.runTest {
- val recommendations by collectLastValue(underTest.recommendations)
-
- val model =
- MediaRecommendationsModel(
- key = KEY_MEDIA_SMARTSPACE,
- packageName = PACKAGE_NAME,
- areRecommendationsValid = true,
- mediaRecs =
- listOf(
- MediaRecModel(icon = icon),
- MediaRecModel(icon = icon),
- MediaRecModel(icon = icon),
- ),
- )
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
-
- assertThat(recommendations).isEqualTo(model)
- }
-
- @Test
- fun addInvalidRecommendation() =
- testScope.runTest {
- val recommendations by collectLastValue(underTest.recommendations)
- val inValidData = smartspaceMediaData.copy(recommendations = listOf())
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
- assertThat(recommendations?.areRecommendationsValid).isTrue()
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, inValidData)
- assertThat(recommendations?.areRecommendationsValid).isFalse()
- assertThat(recommendations?.mediaRecs?.isEmpty()).isTrue()
- }
-
- @Test
- fun removeRecommendation_noTrampolineActivity() {
- val intent = Intent()
-
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
- underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
-
- verify(kosmos.mockBroadcastSender).sendBroadcast(eq(intent))
- }
-
- @Test
- fun removeRecommendation_usingTrampolineActivity() {
- doNothing().whenever(spyContext).startActivity(any())
- val intent = Intent()
-
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- intent.component = ComponentName(PACKAGE_NAME, EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)
-
- underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
-
- verify(spyContext).startActivity(eq(intent))
- }
-
- @Test
- fun startSettings() {
- underTest.startSettings()
-
- verify(activityStarter).startActivity(any(), eq(true))
- }
-
- @Test
- fun startClickIntent() {
- doNothing().whenever(spyContext).startActivity(any())
- val intent = Intent()
- val expandable = mock<Expandable>()
-
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
- underTest.startClickIntent(expandable, intent)
-
- verify(spyContext).startActivity(eq(intent))
- }
-
- companion object {
- private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
- private const val PACKAGE_NAME = "com.example.app"
- private const val SURFACE = 4
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
index 005424ba599e..faa62c2febc1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
@@ -23,7 +23,6 @@ import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
import com.android.systemui.media.controls.ui.viewmodel.mediaControlViewModel
-import com.android.systemui.media.controls.ui.viewmodel.mediaRecommendationsViewModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.fail
@@ -56,25 +55,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
}
@Test
- fun newMediaRecommendationsAdded() {
- val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
- val oldList = listOf<MediaCommonViewModel>()
- val newList = listOf(mediaRecs)
- val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
- val mediaLoadedListUpdateCallback =
- MediaViewModelListUpdateCallback(
- oldList,
- newList,
- { commonViewModel, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
- { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
- { fail("Unexpected to remove $it") },
- { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
- )
-
- DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
- }
-
- @Test
fun updateMediaControl_contentChanged() {
val mediaControl = createMediaControl(InstanceId.fakeInstanceId(123), true)
val oldList = listOf(mediaControl)
@@ -94,25 +74,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
}
@Test
- fun updateMediaRecommendations_contentChanged() {
- val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
- val oldList = listOf(mediaRecs)
- val newList = listOf(mediaRecs.copy(key = KEY_MEDIA_SMARTSPACE_2))
- val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
- val mediaLoadedListUpdateCallback =
- MediaViewModelListUpdateCallback(
- oldList,
- newList,
- { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
- { commonViewModel, _ -> assertThat(commonViewModel).isNotEqualTo(mediaRecs) },
- { fail("Unexpected to remove $it") },
- { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
- )
-
- DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
- }
-
- @Test
fun mediaControlMoved() {
val mediaControl1 = createMediaControl(InstanceId.fakeInstanceId(123), true)
val mediaControl2 = createMediaControl(InstanceId.fakeInstanceId(456), false)
@@ -133,27 +94,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
}
@Test
- fun mediaRecommendationsMoved() {
- val mediaControl1 = createMediaControl(InstanceId.fakeInstanceId(123), true)
- val mediaControl2 = createMediaControl(InstanceId.fakeInstanceId(456), false)
- val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
- val oldList = listOf(mediaRecs, mediaControl1, mediaControl2)
- val newList = listOf(mediaControl1, mediaControl2, mediaRecs)
- val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
- val mediaLoadedListUpdateCallback =
- MediaViewModelListUpdateCallback(
- oldList,
- newList,
- { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
- { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
- { fail("Unexpected to remove $it") },
- { commonViewModel, _, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
- )
-
- DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
- }
-
- @Test
fun mediaControlRemoved() {
val mediaControl = createMediaControl(InstanceId.fakeInstanceId(123), true)
val oldList = listOf(mediaControl)
@@ -172,25 +112,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
}
- @Test
- fun mediaRecommendationsRemoved() {
- val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE_2, false)
- val oldList = listOf(mediaRecs)
- val newList = listOf<MediaCommonViewModel>()
- val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
- val mediaLoadedListUpdateCallback =
- MediaViewModelListUpdateCallback(
- oldList,
- newList,
- { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
- { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
- { commonViewModel -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
- { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
- )
-
- DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
- }
-
private fun createMediaControl(
instanceId: InstanceId,
immediatelyUpdateUi: Boolean,
@@ -201,26 +122,7 @@ class MediaDiffUtilTest : SysuiTestCase() {
controlViewModel = kosmos.mediaControlViewModel,
onAdded = {},
onRemoved = {},
- onUpdated = {}
- )
- }
-
- private fun createMediaRecommendations(
- key: String,
- loadingEnabled: Boolean,
- ): MediaCommonViewModel.MediaRecommendations {
- return MediaCommonViewModel.MediaRecommendations(
- key = key,
- loadingEnabled = loadingEnabled,
- recsViewModel = kosmos.mediaRecommendationsViewModel,
- onAdded = {},
- onRemoved = {},
- onUpdated = {}
+ onUpdated = {},
)
}
-
- companion object {
- private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
- private const val KEY_MEDIA_SMARTSPACE_2 = "MEDIA_SMARTSPACE_ID_2"
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
index fb5bbf452cfa..e56b114dc847 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
@@ -19,23 +19,18 @@ package com.android.systemui.media.controls.ui.viewmodel
import android.R
import android.content.packageManager
import android.content.pm.ApplicationInfo
-import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.mediaLogger
import com.android.systemui.media.controls.shared.mockMediaLogger
import com.android.systemui.media.controls.shared.model.MediaData
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
-import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
@@ -62,15 +57,7 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
private val packageManager = kosmos.packageManager
- private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
private val drawable = context.getDrawable(R.drawable.ic_media_play)
- private val smartspaceMediaData: SmartspaceMediaData =
- SmartspaceMediaData(
- targetId = KEY_MEDIA_SMARTSPACE,
- isActive = true,
- packageName = PACKAGE_NAME,
- recommendations = MediaTestHelper.getValidRecommendationList(icon),
- )
private val underTest: MediaCarouselViewModel = kosmos.mediaCarouselViewModel
@@ -121,53 +108,6 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
}
@Test
- fun loadMediaControlsAndRecommendations_mediaItemsAreUpdated() =
- testScope.runTest {
- val sortedMedia by collectLastValue(underTest.mediaItems)
- val instanceId1 = InstanceId.fakeInstanceId(123)
- val instanceId2 = InstanceId.fakeInstanceId(456)
-
- loadMediaControl(KEY, instanceId1)
- loadMediaControl(KEY_2, instanceId2)
- loadMediaRecommendations()
-
- val firstMediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
- val secondMediaControl = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl
- val recsCard = sortedMedia?.get(2) as MediaCommonViewModel.MediaRecommendations
- assertThat(firstMediaControl.instanceId).isEqualTo(instanceId2)
- assertThat(secondMediaControl.instanceId).isEqualTo(instanceId1)
- assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
- }
-
- @Test
- fun recommendationClicked_switchToPlayer() =
- testScope.runTest {
- val sortedMedia by collectLastValue(underTest.mediaItems)
- kosmos.visualStabilityProvider.isReorderingAllowed = false
- val instanceId = InstanceId.fakeInstanceId(123)
-
- loadMediaRecommendations()
- kosmos.mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME)
-
- var recsCard = sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
- assertThat(sortedMedia).hasSize(1)
- assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
-
- loadMediaControl(KEY, instanceId, false)
-
- recsCard = sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
- assertThat(sortedMedia).hasSize(1)
- assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
-
- loadMediaControl(KEY, instanceId, true)
-
- val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
- assertThat(sortedMedia).hasSize(2)
- assertThat(mediaControl.instanceId).isEqualTo(instanceId)
- assertThat(mediaControl.isMediaFromRec).isTrue()
- }
-
- @Test
fun addMediaControlThenRemove_mediaEventsAreLogged() =
testScope.runTest {
val sortedMedia by collectLastValue(underTest.mediaItems)
@@ -199,31 +139,6 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
verify(kosmos.mediaLogger).logMediaCardRemoved(eq(instanceId))
}
- @Test
- fun addMediaRecommendationThenRemove_mediaEventsAreLogged() =
- testScope.runTest {
- val sortedMedia by collectLastValue(underTest.mediaItems)
-
- loadMediaRecommendations()
-
- val mediaRecommendations =
- sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
- assertThat(mediaRecommendations.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
-
- // when media recommendation is added to carousel
- mediaRecommendations.onAdded(mediaRecommendations)
-
- verify(kosmos.mediaLogger).logMediaRecommendationCardAdded(eq(KEY_MEDIA_SMARTSPACE))
-
- mediaDataFilter.onSmartspaceMediaDataRemoved(KEY, true)
- assertThat(sortedMedia).isEmpty()
-
- // when media recommendation is removed from carousel
- mediaRecommendations.onRemoved(true)
-
- verify(kosmos.mediaLogger).logMediaRecommendationCardRemoved(eq(KEY_MEDIA_SMARTSPACE))
- }
-
private fun loadMediaControl(key: String, instanceId: InstanceId, isPlaying: Boolean = true) {
whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
@@ -239,15 +154,10 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
mediaDataFilter.onMediaDataLoaded(key, key, mediaData)
}
- private fun loadMediaRecommendations(key: String = KEY_MEDIA_SMARTSPACE) {
- mediaDataFilter.onSmartspaceMediaDataLoaded(key, smartspaceMediaData)
- }
-
companion object {
private const val USER_ID = 0
private const val KEY = "key"
private const val KEY_2 = "key2"
private const val PACKAGE_NAME = "com.example.app"
- private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt
deleted file mode 100644
index 51b1911be5d5..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.viewmodel
-
-import android.R
-import android.content.packageManager
-import android.content.pm.ApplicationInfo
-import android.graphics.drawable.Icon
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.MediaTestHelper
-import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
-import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MediaRecommendationsViewModelTest : SysuiTestCase() {
-
- private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
-
- private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
- private val packageManager = kosmos.packageManager
- private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
- private val drawable = context.getDrawable(R.drawable.ic_media_play)
- private val smartspaceMediaData: SmartspaceMediaData =
- SmartspaceMediaData(
- targetId = KEY_MEDIA_SMARTSPACE,
- isActive = true,
- packageName = PACKAGE_NAME,
- recommendations = MediaTestHelper.getValidRecommendationList(icon),
- )
-
- private val underTest: MediaRecommendationsViewModel = kosmos.mediaRecommendationsViewModel
-
- @Test
- fun loadRecommendations_recsCardViewModelIsLoaded() =
- testScope.runTest {
- whenever(packageManager.getApplicationIcon(Mockito.anyString())).thenReturn(drawable)
- whenever(packageManager.getApplicationIcon(any(ApplicationInfo::class.java)))
- .thenReturn(drawable)
- whenever(packageManager.getApplicationInfo(eq(PACKAGE_NAME), ArgumentMatchers.anyInt()))
- .thenReturn(ApplicationInfo())
- whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
- val recsCardViewModel by collectLastValue(underTest.mediaRecsCard)
-
- context.setMockPackageManager(packageManager)
-
- mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
-
- assertThat(recsCardViewModel).isNotNull()
- assertThat(recsCardViewModel?.mediaRecs?.size)
- .isEqualTo(smartspaceMediaData.recommendations.size)
- }
-
- companion object {
- private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
- private const val PACKAGE_NAME = "com.example.app"
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateOverrideTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateOverrideTest.kt
new file mode 100644
index 000000000000..24bd8adaa45a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateOverrideTest.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.model
+
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.Before
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.never
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SysUIStateOverrideTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val defaultState = kosmos.sysUiState
+ private val callbackOnOverride = mock<SysUiState.SysUiStateCallback>()
+ private val dumpManager = kosmos.dumpManager
+
+ private val underTest = kosmos.sysUiStateOverrideFactory.invoke(DISPLAY_1)
+
+ @Before
+ fun setup() {
+ underTest.start()
+ underTest.addCallback(callbackOnOverride)
+ reset(callbackOnOverride)
+ }
+
+ @Test
+ fun setFlag_setOnDefaultState_propagatedToOverride() {
+ defaultState.setFlag(FLAG_1, true).commitUpdate()
+
+ verify(callbackOnOverride).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
+ verify(callbackOnOverride).onSystemUiStateChanged(FLAG_1, DISPLAY_1)
+ }
+
+ @Test
+ fun setFlag_onOverride_overridesDefaultOnes() {
+ defaultState.setFlag(FLAG_1, false).setFlag(FLAG_2, true).commitUpdate()
+ underTest.setFlag(FLAG_1, true).setFlag(FLAG_2, false).commitUpdate()
+
+ assertThat(underTest.isFlagEnabled(FLAG_1)).isTrue()
+ assertThat(underTest.isFlagEnabled(FLAG_2)).isFalse()
+
+ assertThat(defaultState.isFlagEnabled(FLAG_1)).isFalse()
+ assertThat(defaultState.isFlagEnabled(FLAG_2)).isTrue()
+ }
+
+ @Test
+ fun destroy_callbacksForDefaultStateNotReceivedAnymore() {
+ defaultState.setFlag(FLAG_1, true).commitUpdate()
+
+ verify(callbackOnOverride).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
+
+ reset(callbackOnOverride)
+ underTest.destroy()
+ defaultState.setFlag(FLAG_1, false).commitUpdate()
+
+ verify(callbackOnOverride, never()).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
+ }
+
+ @Test
+ fun init_registersWithDumpManager() {
+ verify(dumpManager).registerNormalDumpable(any(), eq(underTest))
+ }
+
+ @Test
+ fun destroy_unregistersWithDumpManager() {
+ underTest.destroy()
+
+ verify(dumpManager).unregisterDumpable(ArgumentMatchers.anyString())
+ }
+
+ private companion object {
+ const val DISPLAY_1 = 1
+ const val FLAG_1 = 1L
+ const val FLAG_2 = 2L
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
index f6de6295212b..5bb7f36e4187 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
@@ -140,6 +140,8 @@ public class SysUiStateTest extends SysuiTestCase {
@Test
public void init_registersWithDumpManager() {
+ mFlagsContainer.start();
+
verify(mDumpManager).registerNormalDumpable(any(), eq(mFlagsContainer));
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 9adf24f32c0c..1743e056b65c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -863,7 +863,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasUdfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -885,7 +885,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasUdfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -907,7 +907,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -930,7 +930,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1033,7 +1033,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1056,7 +1056,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1079,7 +1079,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1102,7 +1102,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playSuccessHaptic by
- collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
+ collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)
setupBiometricAuth(hasSfps = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1160,7 +1160,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
@Test
@DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
- fun playsFaceErrorHaptics_nonSfps_coEx() =
+ fun skipsFaceErrorHaptics_nonSfps_coEx() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic)
@@ -1172,15 +1172,14 @@ class SceneContainerStartableTest : SysuiTestCase() {
underTest.start()
updateFaceAuthStatus(isSuccess = false)
- assertThat(playErrorHaptic).isNotNull()
- assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
- verify(vibratorHelper).vibrateAuthError(anyString())
+ assertThat(playErrorHaptic).isNull()
+ verify(vibratorHelper, never()).vibrateAuthError(anyString())
verify(vibratorHelper, never()).vibrateAuthSuccess(anyString())
}
@Test
@EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
- fun playsMSDLFaceErrorHaptics_nonSfps_coEx() =
+ fun skipsMSDLFaceErrorHaptics_nonSfps_coEx() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic)
@@ -1192,10 +1191,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
underTest.start()
updateFaceAuthStatus(isSuccess = false)
- assertThat(playErrorHaptic).isNotNull()
- assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
- assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.FAILURE)
- assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties)
+ assertThat(playErrorHaptic).isNull()
+ assertThat(msdlPlayer.latestTokenPlayed).isNull()
+ assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 2c852c3f6185..94db429c2225 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -598,7 +598,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mKeyguardClockPositionAlgorithm,
mMSDLPlayer,
mBrightnessMirrorShowingRepository,
- new BlurConfig(0f, 0f));
+ new BlurConfig(0f, 0f),
+ () -> mKosmos.getFakeShadeDisplaysRepository());
mNotificationPanelViewController.initDependencies(
mCentralSurfaces,
null,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index f54c36754d31..89263fc42739 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -195,9 +195,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
@EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
public void updateSystemUiStateFlags_updatesSysuiStateInteractor() {
var DISPLAY_ID = 10;
- var displayMock = display(TYPE_INTERNAL, /* flags= */ 0, /* id= */DISPLAY_ID,
- /* state= */ null);
- when(mView.getDisplay()).thenReturn(displayMock);
+ mKosmos.getFakeShadeDisplaysRepository().setPendingDisplayId(DISPLAY_ID);
mNotificationPanelViewController.updateSystemUiStateFlags();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 3407cd50e76f..4a304071ee97 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -41,7 +41,6 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.platform.test.flag.junit.FlagsParameterization;
-import android.provider.Settings;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.view.WindowManager;
@@ -71,7 +70,6 @@ import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
-import com.android.systemui.util.settings.FakeSettings;
import com.google.common.util.concurrent.MoreExecutors;
@@ -113,7 +111,6 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
@Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListener;
- private FakeSettings mSecureSettings;
private final Executor mMainExecutor = MoreExecutors.directExecutor();
private final Executor mBackgroundExecutor = MoreExecutors.directExecutor();
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
@@ -135,9 +132,6 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
- mSecureSettings = new FakeSettings();
- mSecureSettings.putInt(Settings.Secure.DISABLE_SECURE_WINDOWS, 0);
-
// Preferred refresh rate is equal to the first displayMode's refresh rate
mPreferredRefreshRate = mContext.getDisplay().getSystemSupportedModes()[0].getRefreshRate();
overrideResource(
@@ -171,7 +165,6 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
() -> mSelectedUserInteractor,
mUserTracker,
mKosmos.getNotificationShadeWindowModel(),
- mSecureSettings,
mKosmos::getCommunalInteractor,
mKosmos.getShadeLayoutParams());
mNotificationShadeWindowController.setScrimsVisibilityListener((visibility) -> {});
@@ -355,19 +348,6 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
}
@Test
- public void setKeyguardShowingWithSecureWindowsDisabled_disablesSecureFlag() {
- mSecureSettings.putInt(Settings.Secure.DISABLE_SECURE_WINDOWS, 1);
- mNotificationShadeWindowController.setBouncerShowing(true);
-
- verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
- assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) == 0).isTrue();
- assertThat(
- (mLayoutParameters.getValue().inputFeatures & INPUT_FEATURE_SENSITIVE_FOR_PRIVACY)
- != 0)
- .isTrue();
- }
-
- @Test
public void setKeyguardNotShowing_disablesSecureFlag() {
mNotificationShadeWindowController.setBouncerShowing(false);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
index 9498daaf0b07..c635c7ff69a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
@@ -67,7 +67,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
fun policy_changing_propagatedFromTheLatestPolicy() =
testScope.runTest {
val underTest = createUnderTest()
- val displayIds by collectValues(underTest.displayId)
+ val displayIds by collectValues(underTest.pendingDisplayId)
assertThat(displayIds).containsExactly(0)
@@ -98,7 +98,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
DEVELOPMENT_SHADE_DISPLAY_AWARENESS,
FakeShadeDisplayPolicy.name,
)
- val displayId by collectLastValue(underTest.displayId)
+ val displayId by collectLastValue(underTest.pendingDisplayId)
displayRepository.addDisplay(displayId = 1)
@@ -161,7 +161,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
FakeShadeDisplayPolicy.name,
)
- val displayId by collectLastValue(underTest.displayId)
+ val displayId by collectLastValue(underTest.pendingDisplayId)
displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
FakeShadeDisplayPolicy.setDisplayId(2)
@@ -176,4 +176,17 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
assertThat(displayId).isEqualTo(2)
}
+
+ @Test
+ fun onDisplayChangedSucceeded_displayIdChanges() =
+ testScope.runTest {
+ val underTest = createUnderTest()
+ val displayId by collectLastValue(underTest.displayId)
+
+ assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
+
+ underTest.onDisplayChangedSucceeded(1)
+
+ assertThat(displayId).isEqualTo(1)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
index fd6bc98b006c..f51d41bbc80b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
@@ -69,7 +69,7 @@ class ShadePrimaryDisplayCommandTest : SysuiTestCase() {
@Test
fun commandShadeDisplayOverride_resetsDisplayId() =
testScope.runTest {
- val displayId by collectLastValue(shadeDisplaysRepository.displayId)
+ val displayId by collectLastValue(shadeDisplaysRepository.pendingDisplayId)
assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
val newDisplayId = 2
@@ -87,7 +87,7 @@ class ShadePrimaryDisplayCommandTest : SysuiTestCase() {
@Test
fun commandShadeDisplayOverride_anyExternalDisplay_notOnDefaultAnymore() =
testScope.runTest {
- val displayId by collectLastValue(shadeDisplaysRepository.displayId)
+ val displayId by collectLastValue(shadeDisplaysRepository.pendingDisplayId)
assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
val newDisplayId = 2
displayRepository.addDisplay(displayId = newDisplayId)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index 0ad60b617194..03f546b09faf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -22,7 +22,6 @@ import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.ui.data.repository.configurationRepository
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
@@ -82,7 +81,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInCorrectPosition_notAddedOrRemoved() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(0)
+ positionRepository.setPendingDisplayId(0)
underTest.start()
@@ -93,18 +92,19 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInWrongPosition_changes() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
underTest.start()
verify(shadeContext).reparentToDisplay(eq(1))
+ assertThat(positionRepository.displayId.value).isEqualTo(1)
}
@Test
fun start_shadeInWrongPosition_logsStartToLatencyTracker() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
underTest.start()
@@ -115,7 +115,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInWrongPosition_someNotificationsVisible_hiddenThenShown() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
activeNotificationRepository.setActiveNotifs(1)
underTest.start()
@@ -129,7 +129,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInWrongPosition_someNotificationsVisible_waitsForInflationsBeforeShowingNssl() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
activeNotificationRepository.setActiveNotifs(1)
val endRebinding = notificationRebindingTracker.trackRebinding("test")
@@ -155,7 +155,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInWrongPosition_noNotifications_nsslNotHidden() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
activeNotificationRepository.setActiveNotifs(0)
underTest.start()
@@ -170,7 +170,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
fun start_shadeInWrongPosition_waitsUntilMovedToDisplayReceived() =
testScope.runTest {
whenever(display.displayId).thenReturn(0)
- positionRepository.setDisplayId(1)
+ positionRepository.setPendingDisplayId(1)
activeNotificationRepository.setActiveNotifs(1)
underTest.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index 4f301031e77c..0642467a001b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
@@ -19,6 +19,8 @@ package com.android.systemui.shared.clocks
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.Drawable
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.util.TypedValue
import android.view.LayoutInflater
import android.widget.FrameLayout
@@ -29,6 +31,7 @@ import com.android.systemui.customization.R
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.plugins.clocks.ClockSettings
import com.android.systemui.plugins.clocks.ThemeConfig
+import com.android.systemui.shared.Flags
import com.android.systemui.shared.clocks.DefaultClockController.Companion.DOZE_COLOR
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -103,14 +106,34 @@ class DefaultClockProviderTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_AMBIENT_AOD)
+ fun defaultClock_initialize_flagOff() {
+ val clock = provider.createClock(DEFAULT_CLOCK_ID)
+ verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+ verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+
+ clock.initialize(true, 0f, 0f, null)
+
+ // This is the default darkTheme color
+ val expectedColor = context.resources.getColor(android.R.color.system_accent1_100)
+ verify(mockSmallClockView).setColors(DOZE_COLOR, expectedColor)
+ verify(mockLargeClockView).setColors(DOZE_COLOR, expectedColor)
+ verify(mockSmallClockView).onTimeZoneChanged(notNull())
+ verify(mockLargeClockView).onTimeZoneChanged(notNull())
+ verify(mockSmallClockView).refreshTime()
+ verify(mockLargeClockView).refreshTime()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_AMBIENT_AOD)
fun defaultClock_initialize() {
val clock = provider.createClock(DEFAULT_CLOCK_ID)
verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
- clock.initialize(true, 0f, 0f, {})
+ clock.initialize(true, 0f, 0f, null)
- val expectedColor = 0
+ val expectedColor = Color.MAGENTA
verify(mockSmallClockView).setColors(DOZE_COLOR, expectedColor)
verify(mockLargeClockView).setColors(DOZE_COLOR, expectedColor)
verify(mockSmallClockView).onTimeZoneChanged(notNull())
@@ -165,8 +188,10 @@ class DefaultClockProviderTest : SysuiTestCase() {
}
@Test
- fun defaultClock_events_onThemeChanged_noSeed() {
- val expectedColor = 0
+ @DisableFlags(Flags.FLAG_AMBIENT_AOD)
+ fun defaultClock_events_onThemeChanged_noSeed_flagOff() {
+ // This is the default darkTheme color
+ val expectedColor = context.resources.getColor(android.R.color.system_accent1_100)
val clock = provider.createClock(DEFAULT_CLOCK_ID)
verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
@@ -180,6 +205,22 @@ class DefaultClockProviderTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_AMBIENT_AOD)
+ fun defaultClock_events_onThemeChanged_noSeedn() {
+ val expectedColor = Color.TRANSPARENT
+ val clock = provider.createClock(DEFAULT_CLOCK_ID)
+
+ verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+ verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+
+ clock.smallClock.events.onThemeChanged(ThemeConfig(true, null))
+ clock.largeClock.events.onThemeChanged(ThemeConfig(true, null))
+
+ verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+ verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+ }
+
+ @Test
fun defaultClock_events_onThemeChanged_newSeed() {
val initSeedColor = 10
val newSeedColor = 20
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
index 4bd02e0fab22..17509dc6a80f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
@@ -19,6 +19,10 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ConditionExtensionsTest : SysuiTestCase() {
private lateinit var testScope: TestScope
+ private val testCallback =
+ Condition.Callback {
+ // This is a no-op
+ }
@Before
fun setUp() {
@@ -33,7 +37,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
assertThat(condition.isConditionSet).isFalse()
- condition.start()
+ condition.testStart()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isTrue()
}
@@ -46,7 +50,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
assertThat(condition.isConditionSet).isFalse()
- condition.start()
+ condition.testStart()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
}
@@ -56,7 +60,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
testScope.runTest {
val flow = emptyFlow<Boolean>()
val condition = flow.toCondition(scope = this, Condition.START_EAGERLY)
- condition.start()
+ condition.testStop()
assertThat(condition.isConditionSet).isFalse()
assertThat(condition.isConditionMet).isFalse()
@@ -72,7 +76,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
strategy = Condition.START_EAGERLY,
initialValue = true,
)
- condition.start()
+ condition.testStart()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isTrue()
@@ -88,7 +92,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
strategy = Condition.START_EAGERLY,
initialValue = false,
)
- condition.start()
+ condition.testStart()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
@@ -99,7 +103,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
testScope.runTest {
val flow = MutableStateFlow(false)
val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY)
- condition.start()
+ condition.testStart()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
@@ -110,7 +114,7 @@ class ConditionExtensionsTest : SysuiTestCase() {
flow.value = false
assertThat(condition.isConditionMet).isFalse()
- condition.stop()
+ condition.testStop()
}
@Test
@@ -120,10 +124,18 @@ class ConditionExtensionsTest : SysuiTestCase() {
val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY)
assertThat(flow.subscriptionCount.value).isEqualTo(0)
- condition.start()
+ condition.testStart()
assertThat(flow.subscriptionCount.value).isEqualTo(1)
- condition.stop()
+ condition.testStop()
assertThat(flow.subscriptionCount.value).isEqualTo(0)
}
+
+ fun Condition.testStart() {
+ addCallback(testCallback)
+ }
+
+ fun Condition.testStop() {
+ removeCallback(testCallback)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
index 5416536305fc..da660e2f6009 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
@@ -40,7 +40,7 @@ public class FakeCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 326d8ffd3c7c..8165d45c93df 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -34,6 +34,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
import com.android.systemui.shade.ShadeExpansionChangeEvent
+import com.android.systemui.shared.Flags as SharedFlags
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScrimController
@@ -43,10 +44,11 @@ import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.testKosmos
import com.android.systemui.util.WallpaperController
import com.android.systemui.util.mockito.eq
-import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor
import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
import com.android.wm.shell.appzoomout.AppZoomOut
import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import java.util.function.Consumer
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -67,8 +69,6 @@ import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
-import java.util.Optional
-import java.util.function.Consumer
@RunWith(AndroidJUnit4::class)
@RunWithLooper
@@ -76,7 +76,6 @@ import java.util.function.Consumer
class NotificationShadeDepthControllerTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private val applicationScope = kosmos.testScope.backgroundScope
@Mock private lateinit var windowRootViewBlurInteractor: WindowRootViewBlurInteractor
@Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var blurUtils: BlurUtils
@@ -85,7 +84,6 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
@Mock private lateinit var keyguardInteractor: KeyguardInteractor
@Mock private lateinit var choreographer: Choreographer
@Mock private lateinit var wallpaperController: WallpaperController
- @Mock private lateinit var wallpaperInteractor: WallpaperInteractor
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var appZoomOutOptional: Optional<AppZoomOut>
@@ -130,14 +128,12 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
keyguardInteractor,
choreographer,
wallpaperController,
- wallpaperInteractor,
notificationShadeWindowController,
dozeParameters,
context,
ResourcesSplitShadeStateController(),
windowRootViewBlurInteractor,
appZoomOutOptional,
- applicationScope,
dumpManager,
configurationController,
)
@@ -314,21 +310,19 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
}
@Test
- fun onDozeAmountChanged_doesNotApplyBlurWithAmbientAod() {
- notificationShadeDepthController.wallpaperSupportsAmbientMode = false
-
+ @DisableFlags(SharedFlags.FLAG_AMBIENT_AOD)
+ fun onDozeAmountChanged_appliesBlur() {
statusBarStateListener.onDozeAmountChanged(1f, 1f)
notificationShadeDepthController.updateBlurCallback.doFrame(0)
- verify(blurUtils).applyBlur(any(), eq(0), eq(false))
+ verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
}
@Test
- fun onDozeAmountChanged_appliesBlurWithAmbientAod() {
- notificationShadeDepthController.wallpaperSupportsAmbientMode = true
-
+ @EnableFlags(SharedFlags.FLAG_AMBIENT_AOD)
+ fun onDozeAmountChanged_doesNotApplyBlurWithAmbientAod() {
statusBarStateListener.onDozeAmountChanged(1f, 1f)
notificationShadeDepthController.updateBlurCallback.doFrame(0)
- verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
+ verify(blurUtils).applyBlur(any(), eq(0), eq(false))
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
index 7ed2bd38bcd2..0b9b297130a2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
@@ -34,6 +34,8 @@ import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.addNotif
+import com.android.systemui.statusbar.notification.data.repository.removeNotif
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.CallType
@@ -409,6 +411,63 @@ class StatusBarNotificationChipsInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun shownNotificationChips_lastAppVisibleTimeMaintainedAcrossNotifAddsAndRemoves() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.shownNotificationChips)
+
+ val notif1Info = NotifInfo("notif1", mock<StatusBarIconView>(), uid = 100)
+ val notif2Info = NotifInfo("notif2", mock<StatusBarIconView>(), uid = 200)
+
+ // Have notif1's app start as showing and then hide later so we get the chip
+ activityManagerRepository.fake.startingIsAppVisibleValue = true
+ fakeSystemClock.setCurrentTimeMillis(9_000)
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = notif1Info.key,
+ uid = notif1Info.uid,
+ statusBarChipIcon = notif1Info.icon,
+ promotedContent =
+ PromotedNotificationContentModel.Builder(notif1Info.key).build(),
+ )
+ )
+ activityManagerRepository.fake.setIsAppVisible(notif1Info.uid, isAppVisible = false)
+
+ assertThat(latest!![0].key).isEqualTo(notif1Info.key)
+ assertThat(latest!![0].lastAppVisibleTime).isEqualTo(9_000)
+
+ // WHEN a new notification is added
+ activityManagerRepository.fake.startingIsAppVisibleValue = true
+ fakeSystemClock.setCurrentTimeMillis(10_000)
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = notif2Info.key,
+ uid = notif2Info.uid,
+ statusBarChipIcon = notif2Info.icon,
+ promotedContent =
+ PromotedNotificationContentModel.Builder(notif2Info.key).build(),
+ )
+ )
+ activityManagerRepository.fake.setIsAppVisible(notif2Info.uid, isAppVisible = false)
+
+ // THEN the new notification is first
+ assertThat(latest!![0].key).isEqualTo(notif2Info.key)
+ assertThat(latest!![0].lastAppVisibleTime).isEqualTo(10_000)
+
+ // And THEN the original notification maintains its lastAppVisibleTime
+ assertThat(latest!![1].key).isEqualTo(notif1Info.key)
+ assertThat(latest!![1].lastAppVisibleTime).isEqualTo(9_000)
+
+ // WHEN notif1 is removed
+ fakeSystemClock.setCurrentTimeMillis(11_000)
+ activeNotificationListRepository.removeNotif(notif1Info.key)
+
+ // THEN notif2 still has its lastAppVisibleTime
+ assertThat(latest!![0].key).isEqualTo(notif2Info.key)
+ assertThat(latest!![0].lastAppVisibleTime).isEqualTo(10_000)
+ }
+
+ @Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
fun shownNotificationChips_sortedByLastAppVisibleTime() =
kosmos.runTest {
val latest by collectLastValue(underTest.shownNotificationChips)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index 1b5b0d6ff897..e2d1498270c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -16,18 +16,19 @@
package com.android.systemui.statusbar.chips.ui.viewmodel
+import android.content.Context
import android.content.DialogInterface
import android.content.packageManager
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
@@ -181,7 +182,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.primaryChip)
- assertIsCallChip(latest, notificationKey)
+ assertIsCallChip(latest, notificationKey, context)
}
@Test
@@ -196,7 +197,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.primaryChip)
- assertIsCallChip(latest, callNotificationKey)
+ assertIsCallChip(latest, callNotificationKey, context)
// WHEN the higher priority media projection chip is added
mediaProjectionState.value =
@@ -241,7 +242,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
mediaProjectionState.value = MediaProjectionState.NotProjecting
// THEN the lower priority call is used
- assertIsCallChip(latest, callNotificationKey)
+ assertIsCallChip(latest, callNotificationKey, context)
}
/** Regression test for b/347726238. */
@@ -395,18 +396,29 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
}
- fun assertIsCallChip(latest: OngoingActivityChipModel?, notificationKey: String) {
+ fun assertIsCallChip(
+ latest: OngoingActivityChipModel?,
+ notificationKey: String,
+ context: Context,
+ ) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
assertThat((latest as OngoingActivityChipModel.Active).key).isEqualTo(notificationKey)
if (StatusBarConnectedDisplays.isEnabled) {
assertNotificationIcon(latest, notificationKey)
- return
+ } else {
+ val contentDescription =
+ if (latest.icon is OngoingActivityChipModel.ChipIcon.SingleColorIcon) {
+ ((latest.icon) as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
+ .impl
+ .contentDescription
+ } else {
+ (latest.icon as OngoingActivityChipModel.ChipIcon.StatusBarView)
+ .contentDescription
+ }
+ assertThat(contentDescription.loadContentDescription(context))
+ .contains(context.getString(R.string.ongoing_call_content_description))
}
- val icon =
- ((latest.icon) as OngoingActivityChipModel.ChipIcon.SingleColorIcon).impl
- as Icon.Resource
- assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
}
private fun assertNotificationIcon(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
index e3f93f237742..670ebadcf5a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
@@ -62,6 +62,7 @@ import com.android.systemui.statusbar.notification.data.repository.ActiveNotific
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.addNotif
import com.android.systemui.statusbar.notification.data.repository.addNotifs
+import com.android.systemui.statusbar.notification.data.repository.removeNotif
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -254,7 +255,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val unused by collectLastValue(underTest.chips)
assertIsScreenRecordChip(latest!!.primary)
- assertIsCallChip(latest!!.secondary, callNotificationKey)
+ assertIsCallChip(latest!!.secondary, callNotificationKey, context)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
@@ -285,7 +286,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
assertThat(latest!!.active.size).isEqualTo(2)
assertIsScreenRecordChip(latest!!.active[0])
- assertIsCallChip(latest!!.active[1], callNotificationKey)
+ assertIsCallChip(latest!!.active[1], callNotificationKey, context)
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(2)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
@@ -349,6 +350,36 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
.isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
}
+ @EnableChipsModernization
+ @Test
+ fun chips_threeChips_isSmallPortrait_allSquished() =
+ kosmos.runTest {
+ screenRecordState.value = ScreenRecordModel.Recording
+ addOngoingCallState(key = "call")
+
+ val promotedContentBuilder =
+ PromotedNotificationContentModel.Builder("notif").apply {
+ this.shortCriticalText = "Some text here"
+ }
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = promotedContentBuilder.build(),
+ )
+ )
+
+ val latest by collectLastValue(underTest.chips)
+
+ // Squished chips are icon only
+ assertThat(latest!!.active[0])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ assertThat(latest!!.active[1])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ assertThat(latest!!.active[2])
+ .isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ }
+
@DisableChipsModernization
@Test
fun chipsLegacy_countdownChipAndTimerChip_countdownNotSquished_butTimerSquished() =
@@ -617,7 +648,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val unused by collectLastValue(underTest.chips)
assertIsShareToAppChip(latest!!.primary)
- assertIsCallChip(latest!!.secondary, callNotificationKey)
+ assertIsCallChip(latest!!.secondary, callNotificationKey, context)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
@@ -636,7 +667,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
assertThat(latest!!.active.size).isEqualTo(2)
assertIsShareToAppChip(latest!!.active[0])
- assertIsCallChip(latest!!.active[1], callNotificationKey)
+ assertIsCallChip(latest!!.active[1], callNotificationKey, context)
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(2)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
@@ -654,7 +685,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.primaryChip)
- assertIsCallChip(latest, callNotificationKey)
+ assertIsCallChip(latest, callNotificationKey, context)
}
@DisableChipsModernization
@@ -671,7 +702,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.chipsLegacy)
val unused by collectLastValue(underTest.chips)
- assertIsCallChip(latest!!.primary, callNotificationKey)
+ assertIsCallChip(latest!!.primary, callNotificationKey, context)
assertThat(latest!!.secondary)
.isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
@@ -691,7 +722,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val unused by collectLastValue(underTest.chipsLegacy)
assertThat(latest!!.active.size).isEqualTo(1)
- assertIsCallChip(latest!!.active[0], callNotificationKey)
+ assertIsCallChip(latest!!.active[0], callNotificationKey, context)
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(3)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
@@ -851,7 +882,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
@EnableChipsModernization
@Test
- fun chips_threePromotedNotifs_topTwoActiveThirdInOverflow() =
+ fun chips_fourPromotedNotifs_topThreeActiveFourthInOverflow() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
val unused by collectLastValue(underTest.chipsLegacy)
@@ -859,6 +890,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val firstIcon = createStatusBarIconViewOrNull()
val secondIcon = createStatusBarIconViewOrNull()
val thirdIcon = createStatusBarIconViewOrNull()
+ val fourthIcon = createStatusBarIconViewOrNull()
setNotifs(
listOf(
activeNotificationModel(
@@ -879,20 +911,27 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
promotedContent =
PromotedNotificationContentModel.Builder("thirdNotif").build(),
),
+ activeNotificationModel(
+ key = "fourthNotif",
+ statusBarChipIcon = thirdIcon,
+ promotedContent =
+ PromotedNotificationContentModel.Builder("fourthNotif").build(),
+ ),
)
)
- assertThat(latest!!.active.size).isEqualTo(2)
+ assertThat(latest!!.active.size).isEqualTo(3)
assertIsNotifChip(latest!!.active[0], context, firstIcon, "firstNotif")
assertIsNotifChip(latest!!.active[1], context, secondIcon, "secondNotif")
+ assertIsNotifChip(latest!!.active[2], context, thirdIcon, "thirdNotif")
assertThat(latest!!.overflow.size).isEqualTo(1)
- assertIsNotifChip(latest!!.overflow[0], context, thirdIcon, "thirdNotif")
+ assertIsNotifChip(latest!!.overflow[0], context, fourthIcon, "fourthNotif")
assertThat(latest!!.inactive.size).isEqualTo(4)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
@Test
- fun visibleChipKeys_threePromotedNotifs_topTwoInList() =
+ fun visibleChipKeys_fourPromotedNotifs_topThreeInList() =
kosmos.runTest {
val latest by collectLastValue(underTest.visibleChipKeys)
@@ -916,10 +955,16 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
promotedContent =
PromotedNotificationContentModel.Builder("thirdNotif").build(),
),
+ activeNotificationModel(
+ key = "fourthNotif",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent =
+ PromotedNotificationContentModel.Builder("fourthNotif").build(),
+ ),
)
)
- assertThat(latest).containsExactly("firstNotif", "secondNotif").inOrder()
+ assertThat(latest).containsExactly("firstNotif", "secondNotif", "thirdNotif").inOrder()
}
@DisableChipsModernization
@@ -950,14 +995,14 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
)
)
- assertIsCallChip(latest!!.primary, callNotificationKey)
+ assertIsCallChip(latest!!.primary, callNotificationKey, context)
assertIsNotifChip(latest!!.secondary, context, firstIcon, "firstNotif")
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
@EnableChipsModernization
@Test
- fun chips_callAndPromotedNotifs_callAndFirstNotifActiveSecondNotifInOverflow() =
+ fun chips_callAndPromotedNotifs_callAndFirstTwoNotifsActive_thirdNotifInOverflow() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
val unused by collectLastValue(underTest.chipsLegacy)
@@ -965,6 +1010,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val callNotificationKey = "call"
val firstIcon = createStatusBarIconViewOrNull()
val secondIcon = createStatusBarIconViewOrNull()
+ val thirdIcon = createStatusBarIconViewOrNull()
addOngoingCallState(key = callNotificationKey)
activeNotificationListRepository.addNotifs(
listOf(
@@ -980,21 +1026,28 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
promotedContent =
PromotedNotificationContentModel.Builder("secondNotif").build(),
),
+ activeNotificationModel(
+ key = "thirdNotif",
+ statusBarChipIcon = thirdIcon,
+ promotedContent =
+ PromotedNotificationContentModel.Builder("thirdNotif").build(),
+ ),
)
)
- assertThat(latest!!.active.size).isEqualTo(2)
- assertIsCallChip(latest!!.active[0], callNotificationKey)
+ assertThat(latest!!.active.size).isEqualTo(3)
+ assertIsCallChip(latest!!.active[0], callNotificationKey, context)
assertIsNotifChip(latest!!.active[1], context, firstIcon, "firstNotif")
+ assertIsNotifChip(latest!!.active[2], context, secondIcon, "secondNotif")
assertThat(latest!!.overflow.size).isEqualTo(1)
- assertIsNotifChip(latest!!.overflow[0], context, secondIcon, "secondNotif")
+ assertIsNotifChip(latest!!.overflow[0], context, thirdIcon, "thirdNotif")
assertThat(latest!!.inactive.size).isEqualTo(3)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
@DisableChipsModernization
@Test
- fun chipsLegacy_screenRecordAndCallAndPromotedNotifs_notifsNotShown() =
+ fun chipsLegacy_screenRecordAndCallAndPromotedNotif_notifNotShown() =
kosmos.runTest {
val callNotificationKey = "call"
val latest by collectLastValue(underTest.chipsLegacy)
@@ -1011,12 +1064,12 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
)
assertIsScreenRecordChip(latest!!.primary)
- assertIsCallChip(latest!!.secondary, callNotificationKey)
+ assertIsCallChip(latest!!.secondary, callNotificationKey, context)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
}
@Test
- fun visibleChipKeys_screenRecordAndCallAndPromotedNotifs_topTwoInList() =
+ fun visibleChipKeys_screenRecordAndCallAndPromotedNotifs_topThreeInList() =
kosmos.runTest {
val latest by collectLastValue(underTest.visibleChipKeys)
@@ -1025,20 +1078,27 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
screenRecordState.value = ScreenRecordModel.Recording
activeNotificationListRepository.addNotif(
activeNotificationModel(
- key = "notif",
+ key = "notif1",
statusBarChipIcon = createStatusBarIconViewOrNull(),
- promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif1").build(),
+ )
+ )
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif2",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif2").build(),
)
)
assertThat(latest)
- .containsExactly(ScreenRecordChipViewModel.KEY, callNotificationKey)
+ .containsExactly(ScreenRecordChipViewModel.KEY, callNotificationKey, "notif1")
.inOrder()
}
@EnableChipsModernization
@Test
- fun chips_screenRecordAndCallAndPromotedNotif_notifInOverflow() =
+ fun chips_screenRecordAndCallAndPromotedNotifs_secondNotifInOverflow() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
val unused by collectLastValue(underTest.chipsLegacy)
@@ -1055,11 +1115,22 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
)
addOngoingCallState(key = callNotificationKey)
- assertThat(latest!!.active.size).isEqualTo(2)
+ // This is the overflow notif
+ val notifIcon2 = createStatusBarIconViewOrNull()
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif2",
+ statusBarChipIcon = notifIcon2,
+ promotedContent = PromotedNotificationContentModel.Builder("notif2").build(),
+ )
+ )
+
+ assertThat(latest!!.active.size).isEqualTo(3)
assertIsScreenRecordChip(latest!!.active[0])
- assertIsCallChip(latest!!.active[1], callNotificationKey)
+ assertIsCallChip(latest!!.active[1], callNotificationKey, context)
+ assertIsNotifChip(latest!!.active[2], context, notifIcon, "notif")
assertThat(latest!!.overflow.size).isEqualTo(1)
- assertIsNotifChip(latest!!.overflow[0], context, notifIcon, "notif")
+ assertIsNotifChip(latest!!.overflow[0], context, notifIcon2, "notif2")
assertThat(latest!!.inactive.size).isEqualTo(2)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
}
@@ -1092,7 +1163,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
addOngoingCallState(callNotificationKey)
// THEN the higher priority call chip is used
- assertIsCallChip(latest, callNotificationKey)
+ assertIsCallChip(latest, callNotificationKey, context)
// WHEN the higher priority media projection chip is added
mediaProjectionState.value =
@@ -1145,7 +1216,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
mediaProjectionState.value = MediaProjectionState.NotProjecting
// THEN the lower priority call is used
- assertIsCallChip(latest, callNotificationKey)
+ assertIsCallChip(latest, callNotificationKey, context)
// WHEN the higher priority call is removed
removeOngoingCallState(key = callNotificationKey)
@@ -1186,7 +1257,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
// THEN the higher priority call chip is used as primary and notif is demoted to
// secondary
- assertIsCallChip(latest!!.primary, callNotificationKey)
+ assertIsCallChip(latest!!.primary, callNotificationKey, context)
assertIsNotifChip(latest!!.secondary, context, notifIcon, "notif")
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
@@ -1201,7 +1272,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
// THEN the higher priority media projection chip is used as primary and call is demoted
// to secondary (and notif is dropped altogether)
assertIsShareToAppChip(latest!!.primary)
- assertIsCallChip(latest!!.secondary, callNotificationKey)
+ assertIsCallChip(latest!!.secondary, callNotificationKey, context)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModel())
// WHEN the higher priority screen record chip is added
@@ -1234,15 +1305,16 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
@Test
fun chips_movesChipsAroundAccordingToPriority() =
kosmos.runTest {
+ systemClock.setCurrentTimeMillis(10_000)
val callNotificationKey = "call"
// Start with just the lowest priority chip active
- val notifIcon = createStatusBarIconViewOrNull()
+ val notif1Icon = createStatusBarIconViewOrNull()
setNotifs(
listOf(
activeNotificationModel(
- key = "notif",
- statusBarChipIcon = notifIcon,
- promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
+ key = "notif1",
+ statusBarChipIcon = notif1Icon,
+ promotedContent = PromotedNotificationContentModel.Builder("notif1").build(),
)
)
)
@@ -1254,7 +1326,7 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
val unused by collectLastValue(underTest.chipsLegacy)
assertThat(latest!!.active.size).isEqualTo(1)
- assertIsNotifChip(latest!!.active[0], context, notifIcon, "notif")
+ assertIsNotifChip(latest!!.active[0], context, notif1Icon, "notif1")
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(4)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
@@ -1262,10 +1334,10 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
// WHEN the higher priority call chip is added
addOngoingCallState(key = callNotificationKey)
- // THEN the higher priority call chip and notif are active in that order
+ // THEN the higher priority call chip and notif1 are active in that order
assertThat(latest!!.active.size).isEqualTo(2)
- assertIsCallChip(latest!!.active[0], callNotificationKey)
- assertIsNotifChip(latest!!.active[1], context, notifIcon, "notif")
+ assertIsCallChip(latest!!.active[0], callNotificationKey, context)
+ assertIsNotifChip(latest!!.active[1], context, notif1Icon, "notif1")
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(3)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
@@ -1278,56 +1350,63 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
createTask(taskId = 1),
)
- // THEN the higher priority media projection chip and call are active in that order, and
- // notif is demoted to overflow
- assertThat(latest!!.active.size).isEqualTo(2)
+ // THEN media projection, then call, then notif1 are active
+ assertThat(latest!!.active.size).isEqualTo(3)
assertIsShareToAppChip(latest!!.active[0])
- assertIsCallChip(latest!!.active[1], callNotificationKey)
- assertThat(latest!!.overflow.size).isEqualTo(1)
- assertIsNotifChip(latest!!.overflow[0], context, notifIcon, "notif")
+ assertIsCallChip(latest!!.active[1], callNotificationKey, context)
+ assertIsNotifChip(latest!!.active[2], context, notif1Icon, "notif1")
+ assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(2)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
- // WHEN the higher priority screen record chip is added
+ // WHEN the screen record chip is added, which replaces media projection
screenRecordState.value = ScreenRecordModel.Recording
+ // AND another notification is added
+ systemClock.advanceTime(2_000)
+ val notif2Icon = createStatusBarIconViewOrNull()
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif2",
+ statusBarChipIcon = notif2Icon,
+ promotedContent = PromotedNotificationContentModel.Builder("notif2").build(),
+ )
+ )
- // THEN the higher priority screen record chip and call are active in that order, and
- // media projection and notif are demoted in overflow
- assertThat(latest!!.active.size).isEqualTo(2)
+ // THEN screen record, then call, then notif2 are active
+ assertThat(latest!!.active.size).isEqualTo(3)
assertIsScreenRecordChip(latest!!.active[0])
- assertIsCallChip(latest!!.active[1], callNotificationKey)
+ assertIsCallChip(latest!!.active[1], callNotificationKey, context)
+ assertIsNotifChip(latest!!.active[2], context, notif2Icon, "notif2")
+
+ // AND notif1 and media projection is demoted in overflow
assertThat(latest!!.overflow.size).isEqualTo(2)
assertIsShareToAppChip(latest!!.overflow[0])
- assertIsNotifChip(latest!!.overflow[1], context, notifIcon, "notif")
+ assertIsNotifChip(latest!!.overflow[1], context, notif1Icon, "notif1")
assertThat(latest!!.inactive.size).isEqualTo(1)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
- // WHEN screen record and call is dropped
+ // WHEN screen record and call are dropped
screenRecordState.value = ScreenRecordModel.DoingNothing
- setNotifs(
- listOf(
- activeNotificationModel(
- key = "notif",
- statusBarChipIcon = notifIcon,
- promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
- )
- )
- )
+ removeOngoingCallState(callNotificationKey)
- // THEN media projection and notif remain
- assertThat(latest!!.active.size).isEqualTo(2)
+ // THEN media projection, notif2, and notif1 remain
+ assertThat(latest!!.active.size).isEqualTo(3)
assertIsShareToAppChip(latest!!.active[0])
- assertIsNotifChip(latest!!.active[1], context, notifIcon, "notif")
+ assertIsNotifChip(latest!!.active[1], context, notif2Icon, "notif2")
+ assertIsNotifChip(latest!!.active[2], context, notif1Icon, "notif1")
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(3)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
// WHEN media projection is dropped
mediaProjectionState.value = MediaProjectionState.NotProjecting
+ // AND notif2 is dropped
+ systemClock.advanceTime(2_000)
+ activeNotificationListRepository.removeNotif("notif2")
- // THEN only notif is active
+ // THEN only notif1 is active
assertThat(latest!!.active.size).isEqualTo(1)
- assertIsNotifChip(latest!!.active[0], context, notifIcon, "notif")
+ assertIsNotifChip(latest!!.active[0], context, notif1Icon, "notif1")
assertThat(latest!!.overflow).isEmpty()
assertThat(latest!!.inactive.size).isEqualTo(4)
assertThat(unused).isEqualTo(MultipleOngoingActivityChipsModelLegacy())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
index d36dbbe8d36f..d4518e7299da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
@@ -21,9 +21,10 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.parameterizeSceneContainerFlag
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.lifecycle.activateIn
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
@@ -47,7 +48,8 @@ import platform.test.runner.parameterized.Parameters
class MediaControlChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val mediaControlChipInteractor by lazy { kosmos.mediaControlChipInteractor }
- private val Kosmos.underTest by Kosmos.Fixture { kosmos.mediaControlChipViewModel }
+ private val Kosmos.underTest by
+ Kosmos.Fixture { kosmos.mediaControlChipViewModelFactory.create() }
@Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
companion object {
@@ -62,6 +64,7 @@ class MediaControlChipViewModelTest(flags: FlagsParameterization) : SysuiTestCas
fun setUp() {
MockitoAnnotations.initMocks(this)
mediaControlChipInteractor.initialize()
+ kosmos.underTest.activateIn(kosmos.testScope)
}
init {
@@ -71,7 +74,7 @@ class MediaControlChipViewModelTest(flags: FlagsParameterization) : SysuiTestCas
@Test
fun chip_noActiveMedia_IsHidden() =
kosmos.runTest {
- val chip by collectLastValue(underTest.chip)
+ val chip = underTest.chip
assertThat(chip).isInstanceOf(PopupChipModel.Hidden::class.java)
}
@@ -79,30 +82,26 @@ class MediaControlChipViewModelTest(flags: FlagsParameterization) : SysuiTestCas
@Test
fun chip_activeMedia_IsShown() =
kosmos.runTest {
- val chip by collectLastValue(underTest.chip)
-
val userMedia = MediaData(active = true, song = "test")
updateMedia(userMedia)
- assertThat(chip).isInstanceOf(PopupChipModel.Shown::class.java)
+ assertThat(underTest.chip).isInstanceOf(PopupChipModel.Shown::class.java)
}
@Test
fun chip_songNameChanges_chipTextUpdated() =
kosmos.runTest {
- val chip by collectLastValue(underTest.chip)
-
val initialSongName = "Initial Song"
val newSongName = "New Song"
val userMedia = MediaData(active = true, song = initialSongName)
updateMedia(userMedia)
- assertThat(chip).isInstanceOf(PopupChipModel.Shown::class.java)
- assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(initialSongName)
+ assertThat(underTest.chip).isInstanceOf(PopupChipModel.Shown::class.java)
+ assertThat((underTest.chip as PopupChipModel.Shown).chipText).isEqualTo(initialSongName)
val updatedUserMedia = userMedia.copy(song = newSongName)
updateMedia(updatedUserMedia)
- assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(newSongName)
+ assertThat((underTest.chip as PopupChipModel.Shown).chipText).isEqualTo(newSongName)
}
private fun updateMedia(mediaData: MediaData) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
new file mode 100644
index 000000000000..134ab9322df0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.featurepods.media.ui.viewmodel
+
+import android.platform.test.annotations.EnableFlags
+import androidx.compose.runtime.snapshots.Snapshot
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
+import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.statusBarPopupChipsViewModelFactory
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@EnableFlags(StatusBarPopupChips.FLAG_NAME)
+@RunWith(AndroidJUnit4::class)
+class StatusBarPopupChipsViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val underTest = kosmos.statusBarPopupChipsViewModelFactory.create()
+
+ @Before
+ fun setUp() {
+ underTest.activateIn(kosmos.testScope)
+ }
+
+ @Test
+ fun shownPopupChips_allHidden_empty() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+ assertThat(shownPopupChips).isEmpty()
+ }
+
+ @Test
+ fun shownPopupChips_activeMedia_restHidden_mediaControlChipShown() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+ val userMedia = MediaData(active = true, song = "test")
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ Snapshot.takeSnapshot {
+ assertThat(shownPopupChips).hasSize(1)
+ assertThat(shownPopupChips.first().chipId).isEqualTo(PopupChipId.MediaControl)
+ }
+ }
+
+ @Test
+ fun shownPopupChips_mediaChipToggled_popupShown() =
+ kosmos.runTest {
+ val shownPopupChips = underTest.shownPopupChips
+
+ val userMedia = MediaData(active = true, song = "test")
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ Snapshot.takeSnapshot {
+ assertThat(shownPopupChips).hasSize(1)
+ val mediaChip = shownPopupChips.first()
+ assertThat(mediaChip.isPopupShown).isFalse()
+
+ mediaChip.showPopup.invoke()
+ assertThat(shownPopupChips.first().isPopupShown).isTrue()
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationCloseButtonTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationCloseButtonTest.kt
new file mode 100644
index 000000000000..e4b2e6c9b359
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationCloseButtonTest.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
+import android.app.Notification
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.stub
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import org.junit.Before
+
+private fun getCloseButton(row: ExpandableNotificationRow): View {
+ val contractedView = row.showingLayout?.contractedChild!!
+ return contractedView.findViewById(com.android.internal.R.id.close_button)
+}
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NotificationCloseButtonTest : SysuiTestCase() {
+ private lateinit var helper: NotificationTestHelper
+
+ @Before
+ fun setUp() {
+ helper = NotificationTestHelper(
+ mContext,
+ mDependency,
+ TestableLooper.get(this)
+ )
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_NOTIFICATION_ADD_X_ON_HOVER_TO_DISMISS)
+ fun verifyWhenFeatureDisabled() {
+ // Enable the notification row to dismiss.
+ helper.dismissibilityProvider.stub {
+ on { isDismissable(any()) } doReturn true
+ }
+
+ // By default, the close button should be gone.
+ val row = createNotificationRow()
+ val closeButton = getCloseButton(row)
+ assertThat(closeButton).isNotNull()
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+
+ val hoverEnterEvent = MotionEvent.obtain(
+ 0/*downTime=*/,
+ 0/*eventTime=*/,
+ MotionEvent.ACTION_HOVER_ENTER,
+ 0f/*x=*/,
+ 0f/*y=*/,
+ 0/*metaState*/
+ )
+
+ // The close button should not show if the feature is disabled.
+ row.onInterceptHoverEvent(hoverEnterEvent)
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NOTIFICATION_ADD_X_ON_HOVER_TO_DISMISS)
+ fun verifyOnDismissableNotification() {
+ // Enable the notification row to dismiss.
+ helper.dismissibilityProvider.stub {
+ on { isDismissable(any()) } doReturn true
+ }
+
+ // By default, the close button should be gone.
+ val row = createNotificationRow()
+ val closeButton = getCloseButton(row)
+ assertThat(closeButton).isNotNull()
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+
+ val hoverEnterEvent = MotionEvent.obtain(
+ 0/*downTime=*/,
+ 0/*eventTime=*/,
+ MotionEvent.ACTION_HOVER_ENTER,
+ 0f/*x=*/,
+ 0f/*y=*/,
+ 0/*metaState*/
+ )
+
+ // When the row is hovered, the close button should show.
+ row.onInterceptHoverEvent(hoverEnterEvent)
+ assertThat(closeButton.visibility).isEqualTo(View.VISIBLE)
+
+ val hoverExitEvent = MotionEvent.obtain(
+ 0/*downTime=*/,
+ 0/*eventTime=*/,
+ MotionEvent.ACTION_HOVER_EXIT,
+ 0f/*x=*/,
+ 0f/*y=*/,
+ 0/*metaState*/
+ )
+
+ // When hover exits the row, the close button should be gone again.
+ row.onInterceptHoverEvent(hoverExitEvent)
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NOTIFICATION_ADD_X_ON_HOVER_TO_DISMISS)
+ fun verifyOnUndismissableNotification() {
+ // By default, the close button should be gone.
+ val row = createNotificationRow()
+ val closeButton = getCloseButton(row)
+ assertThat(closeButton).isNotNull()
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+
+ val hoverEnterEvent = MotionEvent.obtain(
+ 0/*downTime=*/,
+ 0/*eventTime=*/,
+ MotionEvent.ACTION_HOVER_ENTER,
+ 0f/*x=*/,
+ 0f/*y=*/,
+ 0/*metaState*/
+ )
+
+ // Because the host notification cannot be dismissed, the close button should not show.
+ row.onInterceptHoverEvent(hoverEnterEvent)
+ assertThat(closeButton.visibility).isEqualTo(View.GONE)
+ }
+
+ private fun createNotificationRow(): ExpandableNotificationRow {
+ val notification = Notification.Builder(context, "channel")
+ .setContentTitle("title")
+ .setContentText("text")
+ .setSmallIcon(R.drawable.ic_person)
+ .build()
+
+ return helper.createRow(notification)
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index 0f1cdac05f7a..fdc6657acd1d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -31,6 +31,8 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
+import com.android.systemui.shade.domain.interactor.enableDualShade
+import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_DELAYED_STACK_FADE_IN
@@ -69,6 +71,7 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
@Test
fun updateBounds() =
testScope.runTest {
+ kosmos.enableSingleShade()
val radius = MutableStateFlow(32)
val leftOffset = MutableStateFlow(0)
val shape by
@@ -106,7 +109,7 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
)
)
- // When: QuickSettings shows up full screen
+ // When: QuickSettings shows up full screen on single shade.
fakeKeyguardRepository.setStatusBarState(StatusBarState.SHADE)
val transitionState =
MutableStateFlow<ObservableTransitionState>(
@@ -115,6 +118,10 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
sceneInteractor.setTransitionState(transitionState)
// Then: shape is null
assertThat(shape).isNull()
+
+ // Same scenario on Dual Shade, shape should have clipping bounds
+ kosmos.enableDualShade()
+ assertThat(shape).isNotNull()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
index 83fd5dcd5f82..a13b8647e170 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
@@ -34,123 +34,122 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWithLooper
-class BundleEntryTest : SysuiTestCase() {
- private lateinit var underTest: BundleEntry
+class BundleEntryAdapterTest : SysuiTestCase() {
+ private lateinit var underTest: BundleEntryAdapter
- @get:Rule
- val setFlagsRule = SetFlagsRule()
+ @get:Rule val setFlagsRule = SetFlagsRule()
@Before
fun setUp() {
- underTest = BundleEntry("key")
+ underTest = BundleEntryAdapter(BundleEntry("key"))
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getParent_adapter() {
- assertThat(underTest.entryAdapter.parent).isEqualTo(GroupEntry.ROOT_ENTRY)
+ assertThat(underTest.parent).isEqualTo(GroupEntry.ROOT_ENTRY)
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isTopLevelEntry_adapter() {
- assertThat(underTest.entryAdapter.isTopLevelEntry).isTrue()
+ assertThat(underTest.isTopLevelEntry).isTrue()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getRow_adapter() {
- assertThat(underTest.entryAdapter.row).isNull()
+ assertThat(underTest.row).isNull()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupRoot_adapter() {
- assertThat(underTest.entryAdapter.isGroupRoot).isTrue()
+ assertThat(underTest.isGroupRoot).isTrue()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getKey_adapter() {
- assertThat(underTest.entryAdapter.key).isEqualTo("key")
+ assertThat(underTest.key).isEqualTo("key")
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isClearable_adapter() {
- assertThat(underTest.entryAdapter.isClearable).isTrue()
+ assertThat(underTest.isClearable).isTrue()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getSummarization_adapter() {
- assertThat(underTest.entryAdapter.summarization).isNull()
+ assertThat(underTest.summarization).isNull()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getContrastedColor_adapter() {
- assertThat(underTest.entryAdapter.getContrastedColor(context, false, Color.WHITE))
+ assertThat(underTest.getContrastedColor(context, false, Color.WHITE))
.isEqualTo(Notification.COLOR_DEFAULT)
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun canPeek_adapter() {
- assertThat(underTest.entryAdapter.canPeek()).isFalse()
+ assertThat(underTest.canPeek()).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getWhen_adapter() {
- assertThat(underTest.entryAdapter.`when`).isEqualTo(0)
+ assertThat(underTest.`when`).isEqualTo(0)
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isColorized() {
- assertThat(underTest.entryAdapter.isColorized).isFalse()
+ assertThat(underTest.isColorized).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getSbn() {
- assertThat(underTest.entryAdapter.sbn).isNull()
+ assertThat(underTest.sbn).isNull()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun canDragAndDrop() {
- assertThat(underTest.entryAdapter.canDragAndDrop()).isFalse()
+ assertThat(underTest.canDragAndDrop()).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isBubble() {
- assertThat(underTest.entryAdapter.isBubbleCapable).isFalse()
+ assertThat(underTest.isBubbleCapable).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getStyle() {
- assertThat(underTest.entryAdapter.style).isNull()
+ assertThat(underTest.style).isNull()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getSectionBucket() {
- assertThat(underTest.entryAdapter.sectionBucket).isEqualTo(underTest.bucket)
+ assertThat(underTest.sectionBucket).isEqualTo(underTest.entry.bucket)
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isAmbient() {
- assertThat(underTest.entryAdapter.isAmbient).isFalse()
+ assertThat(underTest.isAmbient).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun canShowFullScreen() {
- assertThat(underTest.entryAdapter.isFullScreenCapable()).isFalse()
+ assertThat(underTest.isFullScreenCapable()).isFalse()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
new file mode 100644
index 000000000000..b6889afa4e8a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.ActivityManager
+import android.app.Notification
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.os.UserHandle
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.RankingBuilder
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper
+class NotificationEntryAdapterTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory
+ private lateinit var underTest: NotificationEntryAdapter
+
+ @get:Rule val setFlagsRule = SetFlagsRule()
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getParent_adapter() {
+ val ge = GroupEntryBuilder().build()
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(ge)
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.parent).isEqualTo(entry.parent)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isTopLevelEntry_adapter() {
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isTopLevelEntry).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getKey_adapter() {
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.key).isEqualTo(entry.key)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getRow_adapter() {
+ val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .build()
+ entry.row = row
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.row).isEqualTo(entry.row)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isGroupRoot_adapter_groupSummary() {
+ val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setGroupSummary(true)
+ .setGroup("key")
+ .build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .build()
+ entry.row = row
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isGroupRoot).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isGroupRoot_adapter_groupChild() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setGroupSummary(true)
+ .setGroup("key")
+ .build()
+
+ val parent = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
+ val groupEntry = GroupEntryBuilder().setSummary(parent)
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .setParent(groupEntry.build())
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isGroupRoot).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isClearable_adapter() {
+ val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .build()
+ entry.row = row
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isClearable).isEqualTo(entry.isClearable)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getSummarization_adapter() {
+ val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .build()
+ val ranking = RankingBuilder(entry.ranking).setSummarization("hello").build()
+ entry.setRanking(ranking)
+ entry.row = row
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.summarization).isEqualTo("hello")
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getIcons_adapter() {
+ val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setUser(UserHandle(ActivityManager.getCurrentUser()))
+ .build()
+ entry.row = row
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.icons).isEqualTo(entry.icons)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isColorized() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setColorized(true)
+ .build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isColorized).isEqualTo(entry.sbn.notification.isColorized)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getSbn() {
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.sbn).isEqualTo(entry.sbn)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun canDragAndDrop() {
+ val pi = Mockito.mock(PendingIntent::class.java)
+ Mockito.`when`(pi.isActivity).thenReturn(true)
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentIntent(pi)
+ .build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.canDragAndDrop()).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isBubble() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setFlag(Notification.FLAG_BUBBLE, true)
+ .build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isBubbleCapable).isEqualTo(entry.isBubble)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getStyle() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setStyle(Notification.BigTextStyle())
+ .build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.style).isEqualTo(entry.notificationStyle)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun getSectionBucket() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setStyle(Notification.BigTextStyle())
+ .build()
+
+ val entry = NotificationEntryBuilder().setNotification(notification).build()
+ entry.bucket = BUCKET_ALERTING
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.sectionBucket).isEqualTo(BUCKET_ALERTING)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun isAmbient() {
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setImportance(NotificationManager.IMPORTANCE_MIN)
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isAmbient).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun canShowFullScreen() {
+ val notification: Notification =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setFullScreenIntent(Mockito.mock(PendingIntent::class.java), true)
+ .build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setImportance(NotificationManager.IMPORTANCE_MIN)
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+ assertThat(underTest.isFullScreenCapable).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun onNotificationBubbleIconClicked() {
+ val notification: Notification =
+ Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+ val entry =
+ NotificationEntryBuilder()
+ .setNotification(notification)
+ .setImportance(NotificationManager.IMPORTANCE_MIN)
+ .build()
+
+ underTest = factory.create(entry) as NotificationEntryAdapter
+
+ underTest.onNotificationBubbleIconClicked()
+ verify((factory as? EntryAdapterFactoryImpl)?.getNotificationActivityStarter())
+ ?.onNotificationBubbleIconClicked(entry)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 481081344dbb..790b2c343a11 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -21,24 +21,17 @@ import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;
-import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
import static android.app.Notification.FLAG_PROMOTED_ONGOING;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_ALERTING;
-
-import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.Notification;
@@ -66,8 +59,6 @@ import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
@@ -458,336 +449,6 @@ public class NotificationEntryTest extends SysuiTestCase {
// no crash, good
}
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getParent_adapter() {
- GroupEntry ge = new GroupEntryBuilder()
- .build();
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .setParent(ge)
- .build();
-
- assertThat(entry.getEntryAdapter().getParent()).isEqualTo(entry.getParent());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isTopLevelEntry_adapter() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .setParent(GroupEntry.ROOT_ENTRY)
- .build();
-
- assertThat(entry.getEntryAdapter().isTopLevelEntry()).isTrue();
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getKey_adapter() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
-
- assertThat(entry.getEntryAdapter().getKey()).isEqualTo(entry.getKey());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getRow_adapter() {
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- entry.setRow(row);
-
- assertThat(entry.getEntryAdapter().getRow()).isEqualTo(entry.getRow());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isGroupRoot_adapter_groupSummary() {
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setGroupSummary(true)
- .setGroup("key")
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .setParent(GroupEntry.ROOT_ENTRY)
- .build();
- entry.setRow(row);
-
- assertThat(entry.getEntryAdapter().isGroupRoot()).isFalse();
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isGroupRoot_adapter_groupChild() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setGroupSummary(true)
- .setGroup("key")
- .build();
-
- NotificationEntry parent = new NotificationEntryBuilder()
- .setParent(GroupEntry.ROOT_ENTRY)
- .build();
- GroupEntryBuilder groupEntry = new GroupEntryBuilder()
- .setSummary(parent);
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .setParent(groupEntry.build())
- .build();
-
- assertThat(entry.getEntryAdapter().isGroupRoot()).isFalse();
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isClearable_adapter() {
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- entry.setRow(row);
-
- assertThat(entry.getEntryAdapter().isClearable()).isEqualTo(entry.isClearable());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getSummarization_adapter() {
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- Ranking ranking = new RankingBuilder(entry.getRanking())
- .setSummarization("hello")
- .build();
- entry.setRanking(ranking);
- entry.setRow(row);
-
- assertThat(entry.getEntryAdapter().getSummarization()).isEqualTo("hello");
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getIcons_adapter() {
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setChannel(mChannel)
- .setId(mId++)
- .setNotification(notification)
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- entry.setRow(row);
-
- assertThat(entry.getEntryAdapter().getIcons()).isEqualTo(entry.getIcons());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isColorized() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setColorized(true)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- assertThat(entry.getEntryAdapter().isColorized()).isEqualTo(
- entry.getSbn().getNotification().isColorized());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getSbn() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- assertThat(entry.getEntryAdapter().getSbn()).isEqualTo(
- entry.getSbn());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void canDragAndDrop() {
- PendingIntent pi = mock(PendingIntent.class);
- when(pi.isActivity()).thenReturn(true);
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setContentIntent(pi)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- assertThat(entry.getEntryAdapter().canDragAndDrop()).isTrue();
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isBubble() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setFlag(FLAG_BUBBLE, true)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- assertThat(entry.getEntryAdapter().isBubbleCapable()).isEqualTo(entry.isBubble());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getStyle() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setStyle(new Notification.BigTextStyle())
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- assertThat(entry.getEntryAdapter().getStyle()).isEqualTo(entry.getNotificationStyle());
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void getSectionBucket() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setStyle(new Notification.BigTextStyle())
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .build();
- entry.setBucket(BUCKET_ALERTING);
-
- assertThat(entry.getEntryAdapter().getSectionBucket()).isEqualTo(BUCKET_ALERTING);
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void isAmbient() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .setImportance(IMPORTANCE_MIN)
- .build();
-
- assertThat(entry.getEntryAdapter().isAmbient()).isTrue();
- }
-
- @Test
- @EnableFlags(NotificationBundleUi.FLAG_NAME)
- public void canShowFullScreen() {
- Notification notification = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setFullScreenIntent(mock(PendingIntent.class), true)
- .build();
-
- NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .setImportance(IMPORTANCE_MIN)
- .build();
-
- assertThat(entry.getEntryAdapter().isFullScreenCapable()).isTrue();
- }
-
private Notification.Action createContextualAction(String title) {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
index 8e6aedcae506..9e27c79d54b8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -16,8 +16,6 @@
package com.android.systemui.statusbar.notification.collection.render
-import android.os.Build
-import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
@@ -26,6 +24,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.assertLogsWtf
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -36,12 +35,13 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
-import org.junit.Assume
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -54,11 +54,11 @@ import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
class GroupExpansionManagerTest : SysuiTestCase() {
- @get:Rule
- val setFlagsRule = SetFlagsRule()
+ @get:Rule val setFlagsRule = SetFlagsRule()
private lateinit var underTest: GroupExpansionManagerImpl
+ private val kosmos = testKosmos()
private lateinit var testHelper: NotificationTestHelper
private val dumpManager: DumpManager = mock()
private val groupMembershipManager: GroupMembershipManager = mock()
@@ -66,15 +66,14 @@ class GroupExpansionManagerTest : SysuiTestCase() {
private val pipeline: NotifPipeline = mock()
private lateinit var beforeRenderListListener: OnBeforeRenderListListener
+ private val factory: EntryAdapterFactoryImpl = kosmos.entryAdapterFactory
private lateinit var summary1: NotificationEntry
private lateinit var summary2: NotificationEntry
private lateinit var entries: List<ListEntry>
private fun notificationEntry(pkg: String, id: Int, parent: ExpandableNotificationRow?) =
NotificationEntryBuilder().setPkg(pkg).setId(id).build().apply {
- row = testHelper.createRow().apply {
- setIsChildInGroup(true, parent)
- }
+ row = testHelper.createRow().apply { setIsChildInGroup(true, parent) }
}
@Before
@@ -91,7 +90,7 @@ class GroupExpansionManagerTest : SysuiTestCase() {
listOf(
notificationEntry("foo", 2, summary1.row),
notificationEntry("foo", 3, summary1.row),
- notificationEntry("foo", 4, summary1.row)
+ notificationEntry("foo", 4, summary1.row),
)
)
.build(),
@@ -101,11 +100,11 @@ class GroupExpansionManagerTest : SysuiTestCase() {
listOf(
notificationEntry("bar", 2, summary2.row),
notificationEntry("bar", 3, summary2.row),
- notificationEntry("bar", 4, summary2.row)
+ notificationEntry("bar", 4, summary2.row),
)
)
.build(),
- notificationEntry("baz", 1, null)
+ notificationEntry("baz", 1, null),
)
whenever(groupMembershipManager.getGroupSummary(summary1)).thenReturn(summary1)
@@ -135,18 +134,20 @@ class GroupExpansionManagerTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun notifyOnlyOnChange_withEntryAdapter() {
+ val entryAdapter1 = factory.create(summary1)
+ val entryAdapter2 = factory.create(summary2)
var listenerCalledCount = 0
underTest.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
- underTest.setGroupExpanded(summary1.entryAdapter, false)
+ underTest.setGroupExpanded(entryAdapter1, false)
assertThat(listenerCalledCount).isEqualTo(0)
- underTest.setGroupExpanded(summary1.entryAdapter, true)
+ underTest.setGroupExpanded(entryAdapter1, true)
assertThat(listenerCalledCount).isEqualTo(1)
- underTest.setGroupExpanded(summary2.entryAdapter, true)
+ underTest.setGroupExpanded(entryAdapter2, true)
assertThat(listenerCalledCount).isEqualTo(2)
- underTest.setGroupExpanded(summary1.entryAdapter, true)
+ underTest.setGroupExpanded(entryAdapter1, true)
assertThat(listenerCalledCount).isEqualTo(2)
- underTest.setGroupExpanded(summary2.entryAdapter, false)
+ underTest.setGroupExpanded(entryAdapter2, false)
assertThat(listenerCalledCount).isEqualTo(3)
}
@@ -168,16 +169,17 @@ class GroupExpansionManagerTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun expandUnattachedEntryAdapter() {
+ val entryAdapter = factory.create(summary1)
// First, expand the entry when it is attached.
- underTest.setGroupExpanded(summary1.entryAdapter, true)
- assertThat(underTest.isGroupExpanded(summary1.entryAdapter)).isTrue()
+ underTest.setGroupExpanded(entryAdapter, true)
+ assertThat(underTest.isGroupExpanded(entryAdapter)).isTrue()
// Un-attach it, and un-expand it.
NotificationEntryBuilder.setNewParent(summary1, null)
- underTest.setGroupExpanded(summary1.entryAdapter, false)
+ underTest.setGroupExpanded(entryAdapter, false)
// Expanding again should throw.
- assertLogsWtf { underTest.setGroupExpanded(summary1.entryAdapter, true) }
+ assertLogsWtf { underTest.setGroupExpanded(entryAdapter, true) }
}
@Test
@@ -207,6 +209,7 @@ class GroupExpansionManagerTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun syncWithPipeline_withEntryAdapter() {
+ val entryAdapter = factory.create(summary1)
underTest.attach(pipeline)
beforeRenderListListener = withArgCaptor {
verify(pipeline).addOnBeforeRenderListListener(capture())
@@ -219,7 +222,7 @@ class GroupExpansionManagerTest : SysuiTestCase() {
verify(listener, never()).onGroupExpansionChange(any(), any())
// Expand one of the groups.
- underTest.setGroupExpanded(summary1.entryAdapter, true)
+ underTest.setGroupExpanded(entryAdapter, true)
verify(listener).onGroupExpansionChange(summary1.row, true)
// Empty the pipeline list and verify that the group is no longer expanded.
@@ -231,11 +234,15 @@ class GroupExpansionManagerTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupExpanded() {
- underTest.setGroupExpanded(summary1.entryAdapter, true)
-
- assertThat(underTest.isGroupExpanded(summary1.entryAdapter)).isTrue();
- assertThat(underTest.isGroupExpanded(
- (entries[0] as? GroupEntry)?.getChildren()?.get(0)?.entryAdapter))
- .isTrue();
+ val entryAdapter = summary1.row.entryAdapter
+ underTest.setGroupExpanded(entryAdapter, true)
+
+ assertThat(underTest.isGroupExpanded(entryAdapter)).isTrue()
+ assertThat(
+ underTest.isGroupExpanded(
+ (entries[0] as? GroupEntry)?.getChildren()?.get(0)?.row?.entryAdapter
+ )
+ )
+ .isTrue()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
index 2bbf094021cf..0ccf58507696 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
@@ -22,10 +22,13 @@ import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -35,8 +38,10 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class GroupMembershipManagerTest : SysuiTestCase() {
- @get:Rule
- val setFlagsRule = SetFlagsRule()
+ @get:Rule val setFlagsRule = SetFlagsRule()
+
+ private val kosmos = testKosmos()
+ private val factory: EntryAdapterFactoryImpl = kosmos.entryAdapterFactory
private var underTest = GroupMembershipManagerImpl()
@@ -144,14 +149,14 @@ class GroupMembershipManagerTest : SysuiTestCase() {
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isChildEntryAdapterInGroup_topLevel() {
val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
- assertThat(underTest.isChildInGroup(topLevelEntry.entryAdapter)).isFalse()
+ assertThat(underTest.isChildInGroup(factory.create(topLevelEntry))).isFalse()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isChildEntryAdapterInGroup_noParent() {
val noParentEntry = NotificationEntryBuilder().setParent(null).build()
- assertThat(underTest.isChildInGroup(noParentEntry.entryAdapter)).isFalse()
+ assertThat(underTest.isChildInGroup(factory.create(noParentEntry))).isFalse()
}
@Test
@@ -165,7 +170,7 @@ class GroupMembershipManagerTest : SysuiTestCase() {
.build()
GroupEntryBuilder().setKey(groupKey).setSummary(summary).build()
- assertThat(underTest.isChildInGroup(summary.entryAdapter)).isFalse()
+ assertThat(underTest.isChildInGroup(factory.create(summary))).isFalse()
}
@Test
@@ -180,14 +185,14 @@ class GroupMembershipManagerTest : SysuiTestCase() {
val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build()
GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build()
- assertThat(underTest.isChildInGroup(entry.entryAdapter)).isTrue()
+ assertThat(underTest.isChildInGroup(factory.create(entry))).isTrue()
}
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupRoot_topLevelEntry() {
val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
- assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse()
+ assertThat(underTest.isGroupRoot(factory.create(entry))).isFalse()
}
@Test
@@ -201,7 +206,7 @@ class GroupMembershipManagerTest : SysuiTestCase() {
.build()
GroupEntryBuilder().setKey(groupKey).setSummary(summary).build()
- assertThat(underTest.isGroupRoot(summary.entryAdapter)).isTrue()
+ assertThat(underTest.isGroupRoot(factory.create(summary))).isTrue()
}
@Test
@@ -216,6 +221,6 @@ class GroupMembershipManagerTest : SysuiTestCase() {
val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build()
GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build()
- assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse()
+ assertThat(underTest.isGroupRoot(factory.create(entry))).isFalse()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index 216fd2d54a1e..3116143504eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -57,7 +57,8 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
private val underTest = kosmos.promotedNotificationContentExtractor
private val systemClock = kosmos.fakeSystemClock
- private val rowImageInflater = RowImageInflater.newInstance(previousIndex = null)
+ private val rowImageInflater =
+ RowImageInflater.newInstance(previousIndex = null, reinflating = false)
private val imageModelProvider by lazy { rowImageInflater.useForContentModel() }
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index f060caea4f24..bb12eff51288 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -37,9 +37,12 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.SbnBuilder
import com.android.systemui.statusbar.SmartReplyController
import com.android.systemui.statusbar.notification.ColorUpdateLogger
+import com.android.systemui.statusbar.notification.NotificationActivityStarter
import com.android.systemui.statusbar.notification.collection.EntryAdapter
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider
import com.android.systemui.statusbar.notification.collection.render.FakeNodeController
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager
@@ -47,6 +50,7 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember
import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController.BUBBLES_SETTING_URI
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
@@ -112,6 +116,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
private val uiEventLogger: UiEventLogger = mock()
private val msdlPlayer: MSDLPlayer = mock()
private val rebindingTracker: NotificationRebindingTracker = mock()
+ private val entryAdapterFactory: EntryAdapterFactory = mock()
private lateinit var controller: ExpandableNotificationRowController
@Before
@@ -154,6 +159,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
uiEventLogger,
msdlPlayer,
rebindingTracker,
+ entryAdapterFactory,
)
whenever(view.childrenContainer).thenReturn(childrenContainer)
@@ -277,8 +283,10 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
whenever(view.privateLayout).thenReturn(childView)
val entryAdapter = mock(EntryAdapter::class.java)
val sbn =
- SbnBuilder().setNotification(Notification.Builder(mContext).build())
- .setUser(UserHandle.of(view.entry.sbn.userId)).build()
+ SbnBuilder()
+ .setNotification(Notification.Builder(mContext).build())
+ .setUser(UserHandle.of(view.entry.sbn.userId))
+ .build()
whenever(entryAdapter.sbn).thenReturn(sbn)
whenever(view.entryAdapter).thenReturn(entryAdapter)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index ce3aee1d88d2..31413b06e5fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -41,7 +41,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTIO
import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
-import com.android.systemui.statusbar.notification.collection.EntryAdapter
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.promoted.FakePromotedNotificationContentExtractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
@@ -204,7 +203,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
val result =
NotificationRowContentBinderImpl.InflationProgress(
packageContext = mContext,
- rowImageInflater = RowImageInflater.newInstance(null),
+ rowImageInflater = RowImageInflater.newInstance(null, reinflating = false),
remoteViews = NewRemoteViews(),
contentModel = NotificationContentModel(headsUpStatusBarModel),
promotedContent = null,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index c376fad1503f..8e7733bb23ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -70,10 +70,14 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
@@ -87,6 +91,7 @@ import com.android.systemui.statusbar.notification.promoted.FakePromotedNotifica
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -101,11 +106,6 @@ import com.android.systemui.util.time.SystemClock;
import com.android.systemui.util.time.SystemClockImpl;
import com.android.systemui.wmshell.BubblesTestActivity;
-import kotlin.coroutines.CoroutineContext;
-
-import kotlinx.coroutines.flow.StateFlowKt;
-import kotlinx.coroutines.test.TestScope;
-
import org.mockito.ArgumentCaptor;
import java.util.List;
@@ -114,6 +114,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import kotlin.coroutines.CoroutineContext;
+import kotlinx.coroutines.flow.StateFlowKt;
+import kotlinx.coroutines.test.TestScope;
+
/**
* A helper class to create {@link ExpandableNotificationRow} (for both individual and group
* notifications).
@@ -734,7 +738,16 @@ public class NotificationTestHelper {
mBindPipelineEntryListener.onEntryInit(entry);
mBindPipeline.manageRow(entry, row);
+ EntryAdapter entryAdapter = new EntryAdapterFactoryImpl(
+ mock(NotificationActivityStarter.class),
+ mock(MetricsLogger.class),
+ mock(PeopleNotificationIdentifier.class),
+ mock(NotificationIconStyleProvider.class),
+ mock(VisualStabilityCoordinator.class)
+ ).create(entry);
+
row.initialize(
+ entryAdapter,
entry,
mock(RemoteInputViewSubcomponent.Factory.class),
APP_NAME,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index 14bbd38ece2c..761ed6186afc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -27,6 +27,7 @@ import android.view.NotificationHeaderView;
import android.view.View;
import android.widget.RemoteViews;
+import androidx.compose.ui.platform.ComposeView;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -35,7 +36,9 @@ import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderViewModelImpl;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import org.junit.Assert;
import org.junit.Before;
@@ -273,6 +276,22 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
}
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ public void initBundleHeader_composeview_is_initialized_once() {
+ View currentView = mChildrenContainer.getChildAt(mChildrenContainer.getChildCount() - 1);
+ Assert.assertFalse(currentView instanceof ComposeView);
+
+ BundleHeaderViewModelImpl viewModel = new BundleHeaderViewModelImpl();
+ mChildrenContainer.initBundleHeader(viewModel);
+ currentView = mChildrenContainer.getChildAt(mChildrenContainer.getChildCount() - 1);
+ Assert.assertTrue(currentView instanceof ComposeView);
+
+ mChildrenContainer.initBundleHeader(viewModel);
+ View finalView = mChildrenContainer.getChildAt(mChildrenContainer.getChildCount() - 1);
+ Assert.assertEquals(currentView, finalView);
+ }
+
private NotificationHeaderView createHeaderView(boolean lowPriority) {
Notification notification = mNotificationTestHelper.createNotification();
final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
index 31f8590c0378..46430afecbb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
@@ -70,6 +70,7 @@ import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -83,6 +84,7 @@ import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -155,7 +157,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
testScope = kosmos.testScope
shadeViewStateProvider = TestShadeViewStateProvider()
- Mockito.`when`(
+ whenever(
kosmos.mockStatusBarContentInsetsProvider
.getStatusBarContentInsetsForCurrentRotation()
)
@@ -163,9 +165,9 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
- Mockito.`when`(iconManagerFactory.create(ArgumentMatchers.any(), ArgumentMatchers.any()))
+ whenever(iconManagerFactory.create(ArgumentMatchers.any(), ArgumentMatchers.any()))
.thenReturn(iconManager)
- Mockito.`when`(statusBarContentInsetsProviderStore.forDisplay(context.displayId))
+ whenever(statusBarContentInsetsProviderStore.forDisplay(context.displayId))
.thenReturn(kosmos.mockStatusBarContentInsetsProvider)
allowTestableLooperAsMainThread()
looper.runWithLooper {
@@ -174,7 +176,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
LayoutInflater.from(mContext).inflate(R.layout.keyguard_status_bar, null)
as KeyguardStatusBarView
)
- Mockito.`when`(keyguardStatusBarView.getDisplay()).thenReturn(mContext.display)
+ whenever(keyguardStatusBarView.display).thenReturn(mContext.display)
}
controller = createController()
@@ -404,14 +406,14 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
fun updateViewState_alphaAndVisibilityGiven_viewUpdated() {
// Verify the initial values so we know the method triggers changes.
Truth.assertThat(keyguardStatusBarView.alpha).isEqualTo(1f)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
val newAlpha = 0.5f
val newVisibility = View.INVISIBLE
controller.updateViewState(newAlpha, newVisibility)
Truth.assertThat(keyguardStatusBarView.alpha).isEqualTo(newAlpha)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(newVisibility)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(newVisibility)
}
@Test
@@ -423,7 +425,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState(1f, View.VISIBLE)
// Since we're disabled, we stay invisible
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -444,15 +446,15 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
fun updateViewState_bypassEnabledAndShouldListenForFace_viewHidden() {
controller.onViewAttached()
updateStateToKeyguard()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
- Mockito.`when`(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(true)
- Mockito.`when`(keyguardBypassController.bypassEnabled).thenReturn(true)
+ whenever(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(true)
+ whenever(keyguardBypassController.bypassEnabled).thenReturn(true)
onFinishedGoingToSleep()
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -461,13 +463,13 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.onViewAttached()
updateStateToKeyguard()
- Mockito.`when`(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(true)
- Mockito.`when`(keyguardBypassController.bypassEnabled).thenReturn(false)
+ whenever(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(true)
+ whenever(keyguardBypassController.bypassEnabled).thenReturn(false)
onFinishedGoingToSleep()
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -476,13 +478,13 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.onViewAttached()
updateStateToKeyguard()
- Mockito.`when`(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(false)
- Mockito.`when`(keyguardBypassController.bypassEnabled).thenReturn(true)
+ whenever(keyguardUpdateMonitor.shouldListenForFace()).thenReturn(false)
+ whenever(keyguardBypassController.bypassEnabled).thenReturn(true)
onFinishedGoingToSleep()
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -495,7 +497,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -508,7 +510,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -520,7 +522,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -532,7 +534,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -544,7 +546,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -556,7 +558,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -568,7 +570,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.setDozing(true)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -580,7 +582,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.setDozing(false)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -595,7 +597,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.GONE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.GONE)
Truth.assertThat(keyguardStatusBarView.alpha).isEqualTo(0.456f)
}
@@ -611,7 +613,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.updateViewState(0.789f, View.VISIBLE)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.GONE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.GONE)
Truth.assertThat(keyguardStatusBarView.alpha).isEqualTo(0.456f)
}
@@ -635,13 +637,13 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.init()
controller.onViewAttached()
updateStateToKeyguard()
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
controller.setDozing(true)
// setDozing(true) should typically cause the view to hide. But since the flag is on, we
// should ignore these set dozing calls and stay the same visibility.
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -679,7 +681,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
shadeViewStateProvider.setShouldHeadsUpBeVisible(true)
controller.updateForHeadsUp(/* animate= */ false)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
@@ -695,7 +697,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
shadeViewStateProvider.setShouldHeadsUpBeVisible(false)
controller.updateForHeadsUp(/* animate= */ false)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -728,7 +730,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
val str = mContext.getString(com.android.internal.R.string.status_bar_volume)
// GIVEN the setting is off
- Mockito.`when`(secureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
+ whenever(secureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
.thenReturn(0)
// WHEN CollapsedStatusBarFragment builds the blocklist
@@ -744,7 +746,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
val str = mContext.getString(com.android.internal.R.string.status_bar_volume)
// GIVEN the setting is ON
- Mockito.`when`(
+ whenever(
secureSettings.getIntForUser(
Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
0,
@@ -779,42 +781,52 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
controller.onViewAttached()
updateStateToKeyguard()
setDisableSystemInfo(true)
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
controller.animateKeyguardStatusBarIn()
// Since we're disabled, we don't actually animate in and stay invisible
- Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
@Test
fun animateToGlanceableHub_affectsAlpha() =
testScope.runTest {
- controller.init()
- val transitionAlphaAmount = .5f
- ViewUtils.attachView(keyguardStatusBarView)
- looper.processAllMessages()
- updateStateToKeyguard()
- kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
- runCurrent()
- controller.updateCommunalAlphaTransition(transitionAlphaAmount)
- Truth.assertThat(keyguardStatusBarView.getAlpha()).isEqualTo(transitionAlphaAmount)
+ try {
+ controller.init()
+ val transitionAlphaAmount = .5f
+ ViewUtils.attachView(keyguardStatusBarView)
+
+ looper.processAllMessages()
+ updateStateToKeyguard()
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
+ runCurrent()
+ controller.updateCommunalAlphaTransition(transitionAlphaAmount)
+ assertThat(keyguardStatusBarView.getAlpha()).isEqualTo(transitionAlphaAmount)
+ } finally {
+ ViewUtils.detachView(keyguardStatusBarView)
+ }
}
@Test
fun animateToGlanceableHub_alphaResetOnCommunalNotShowing() =
testScope.runTest {
- controller.init()
- val transitionAlphaAmount = .5f
- ViewUtils.attachView(keyguardStatusBarView)
- looper.processAllMessages()
- updateStateToKeyguard()
- kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
- runCurrent()
- controller.updateCommunalAlphaTransition(transitionAlphaAmount)
- kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Blank)
- runCurrent()
- Truth.assertThat(keyguardStatusBarView.getAlpha()).isNotEqualTo(transitionAlphaAmount)
+ try {
+ controller.init()
+ val transitionAlphaAmount = .5f
+ ViewUtils.attachView(keyguardStatusBarView)
+
+ looper.processAllMessages()
+ updateStateToKeyguard()
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
+ runCurrent()
+ controller.updateCommunalAlphaTransition(transitionAlphaAmount)
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Blank)
+ runCurrent()
+ assertThat(keyguardStatusBarView.getAlpha()).isNotEqualTo(transitionAlphaAmount)
+ } finally {
+ ViewUtils.detachView(keyguardStatusBarView)
+ }
}
/**
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt
index 47967b3f0828..670c195ee5a1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.lockscreenShadeTransitionController
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.domain.interactor.notificationAlertsInteractor
@@ -54,6 +55,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.visualInterruptionDecisionProvider
@@ -105,10 +107,14 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() {
private val notificationAlertsInteractor = kosmos.notificationAlertsInteractor
private val visualInterruptionDecisionProvider = kosmos.visualInterruptionDecisionProvider
+ private lateinit var factory: EntryAdapterFactoryImpl
+
private lateinit var underTest: StatusBarNotificationPresenter
@Before
fun setup() {
+ factory = kosmos.entryAdapterFactory
+
underTest = createPresenter()
if (VisualInterruptionRefactor.isEnabled) {
verifyAndCaptureSuppressors()
@@ -451,7 +457,7 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() {
private fun createRow(entry: NotificationEntry): ExpandableNotificationRow {
val row: ExpandableNotificationRow = mock()
if (NotificationBundleUi.isEnabled) {
- whenever(row.entryAdapter).thenReturn(entry.entryAdapter)
+ whenever(row.entryAdapter).thenReturn(factory.create(entry))
} else {
whenever(row.entry).thenReturn(entry)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index 345ddae42798..c23e0e733b41 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -46,7 +46,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry.NotifEntryAdapter;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryAdapter;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
@@ -135,7 +135,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
final NotificationContentView privateLayout = mock(NotificationContentView.class);
final NotificationEntry enrEntry = mock(NotificationEntry.class);
- final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class);
+ final NotificationEntryAdapter enrEntryAdapter = mock(NotificationEntryAdapter.class);
when(enr.getPrivateLayout()).thenReturn(privateLayout);
when(enr.getEntry()).thenReturn(enrEntry);
@@ -178,7 +178,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
// THEN
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
verify(enr).setUserExpanded(true);
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
}
@@ -203,7 +203,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
// THEN
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
verify(enr).setUserExpanded(true);
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
}
@@ -217,7 +217,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
final NotificationContentView privateLayout = mock(NotificationContentView.class);
final NotificationEntry enrEntry = mock(NotificationEntry.class);
- final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class);
+ final NotificationEntryAdapter enrEntryAdapter = mock(NotificationEntryAdapter.class);
when(enr.getPrivateLayout()).thenReturn(privateLayout);
when(enr.getEntry()).thenReturn(enrEntry);
@@ -260,7 +260,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
// THEN
verify(mGroupExpansionManager, never()).toggleGroupExpansion(enrEntry);
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
verify(enr, never()).setUserExpanded(anyBoolean());
verify(privateLayout, never()).setOnExpandedVisibleListener(any());
}
@@ -290,7 +290,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
}
@Test
@@ -318,7 +318,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
}
@Test
@@ -346,7 +346,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
}
@Test
@@ -374,6 +374,6 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner);
verify(enr, never()).setUserExpanded(anyBoolean());
verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class));
- verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class));
+ verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class));
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index a083e59fe263..91b3896332f5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -66,7 +66,7 @@ class FakeHomeStatusBarViewModel(
override val mediaProjectionStopDialogDueToCallEndedState =
MutableStateFlow(MediaProjectionStopDialogModel.Hidden)
- override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
+ override val isHomeStatusBarAllowed = MutableStateFlow(false)
override val canShowOngoingActivityChips: Flow<Boolean> = MutableStateFlow(false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 27aa4bab3deb..12cf3b6cd2cf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -30,6 +30,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.display.data.repository.fake
@@ -57,6 +58,7 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
+import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
@@ -97,7 +99,6 @@ import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.runCurrent
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -502,9 +503,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneLockscreen_notOccluded_false() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneLockscreen_notOccluded_false() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
@@ -513,9 +515,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneLockscreen_occluded_true() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneLockscreen_occluded_true() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null)
@@ -524,9 +527,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_overlayBouncer_false() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_overlayBouncer_false() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
kosmos.sceneContainerRepository.showOverlay(Overlays.Bouncer)
@@ -535,9 +539,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneCommunal_false() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneCommunal_false() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Communal)
@@ -545,9 +550,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneShade_false() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneShade_false() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
@@ -555,9 +561,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneGone_true() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneGone_true() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
@@ -565,9 +572,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneGoneWithNotificationsShadeOverlay_false() =
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_sceneGoneWithNotificationsShadeOverlay_false() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
kosmos.sceneContainerRepository.showOverlay(Overlays.NotificationsShade)
@@ -577,14 +585,104 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneGoneWithQuickSettingsShadeOverlay_false() =
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_QsVisibleButInExternalDisplay_defaultStatusBarVisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.QuickSettingsShade)
+ kosmos.fakeShadeDisplaysRepository.setDisplayId(EXTERNAL_DISPLAY)
+ runCurrent()
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_QsVisibleButInExternalDisplay_withFlagOff_defaultStatusBarInvisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.QuickSettingsShade)
+ kosmos.fakeShadeDisplaysRepository.setDisplayId(EXTERNAL_DISPLAY)
+ runCurrent()
+
+ // Shade position is ignored.
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_qsVisibleInThisDisplay_thisStatusBarInvisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.QuickSettingsShade)
+ kosmos.fakeShadeDisplaysRepository.setDisplayId(DEFAULT_DISPLAY)
+ runCurrent()
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_qsExpandedOnDefaultDisplay_statusBarInAnotherDisplay_visible() =
kosmos.runTest {
- val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+ val underTest = homeStatusBarViewModelFactory(EXTERNAL_DISPLAY)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
kosmos.sceneContainerRepository.showOverlay(Overlays.QuickSettingsShade)
runCurrent()
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun isHomeStatusBarAllowed_onDefaultDisplayLockscreen_invisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ runCurrent()
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableSceneContainer
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun isHomeStatusBarAllowed_onExternalDispalyWithLocksceren_invisible() =
+ kosmos.runTest {
+ val underTest = homeStatusBarViewModelFactory(EXTERNAL_DISPLAY)
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ runCurrent()
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun isHomeStatusBarAllowed_legacy_onDefaultDisplayLockscreen_invisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowed)
+
+ kosmos.fakeKeyguardTransitionRepository.transitionTo(
+ KeyguardState.GONE,
+ KeyguardState.LOCKSCREEN,
+ )
+
+ runCurrent()
+
assertThat(latest).isFalse()
}
@@ -920,7 +1018,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
addOngoingCallState(key = "call")
assertIsScreenRecordChip(latest!!.chips.active[0])
- assertIsCallChip(latest!!.chips.active[1], "call")
+ assertIsCallChip(latest!!.chips.active[1], "call", context)
}
@Test
@@ -1560,4 +1658,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope = testScope,
)
}
+
+ private companion object {
+ const val EXTERNAL_DISPLAY = 1
+ }
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
index 4c1f6450dd78..b52db83d513c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
@@ -42,9 +42,13 @@ interface ClockController {
isDarkTheme: Boolean,
dozeFraction: Float,
foldFraction: Float,
- onBoundsChanged: (RectF) -> Unit,
+ clockListener: ClockEventListener?,
)
/** Optional method for dumping debug information */
fun dump(pw: PrintWriter)
}
+
+interface ClockEventListener {
+ fun onBoundsChanged(bounds: RectF)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
index 029e54658f60..20ee6c120ee8 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
@@ -13,6 +13,7 @@
*/
package com.android.systemui.plugins.clocks
+import android.content.Context
import android.graphics.Rect
import com.android.systemui.plugins.annotations.ProtectedInterface
@@ -60,4 +61,12 @@ data class ThemeConfig(
* value denotes that we should use the seed color for the current system theme.
*/
val seedColor: Int?,
-)
+) {
+ fun getDefaultColor(context: Context): Int {
+ return when {
+ seedColor != null -> seedColor!!
+ isDarkTheme -> context.resources.getColor(android.R.color.system_accent1_100)
+ else -> context.resources.getColor(android.R.color.system_accent2_600)
+ }
+ }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/WeatherData.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/WeatherData.kt
index f920b187e7e5..f59dda049aa1 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/WeatherData.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/WeatherData.kt
@@ -24,6 +24,8 @@ data class WeatherData(
@VisibleForTesting const val TEMPERATURE_KEY = "temperature"
private const val INVALID_WEATHER_ICON_STATE = -1
+ @JvmStatic
+ @JvmOverloads
fun fromBundle(extras: Bundle, touchAction: WeatherTouchAction? = null): WeatherData? {
val description = extras.getString(DESCRIPTION_KEY)
val state =
@@ -46,7 +48,7 @@ data class WeatherData(
state = state,
useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
temperature = temperature,
- touchAction = touchAction
+ touchAction = touchAction,
)
if (DEBUG) {
Log.i(TAG, "Weather data parsed $result from $extras")
@@ -87,53 +89,53 @@ data class WeatherData(
}
// Values for WeatherStateIcon must stay in sync with go/g3-WeatherStateIcon
- enum class WeatherStateIcon(val id: Int) {
- UNKNOWN_ICON(0),
+ enum class WeatherStateIcon(val id: Int, val icon: String) {
+ UNKNOWN_ICON(0, ""),
// Clear, day & night.
- SUNNY(1),
- CLEAR_NIGHT(2),
+ SUNNY(1, "a"),
+ CLEAR_NIGHT(2, "f"),
// Mostly clear, day & night.
- MOSTLY_SUNNY(3),
- MOSTLY_CLEAR_NIGHT(4),
+ MOSTLY_SUNNY(3, "b"),
+ MOSTLY_CLEAR_NIGHT(4, "n"),
// Partly cloudy, day & night.
- PARTLY_CLOUDY(5),
- PARTLY_CLOUDY_NIGHT(6),
+ PARTLY_CLOUDY(5, "b"),
+ PARTLY_CLOUDY_NIGHT(6, "n"),
// Mostly cloudy, day & night.
- MOSTLY_CLOUDY_DAY(7),
- MOSTLY_CLOUDY_NIGHT(8),
- CLOUDY(9),
- HAZE_FOG_DUST_SMOKE(10),
- DRIZZLE(11),
- HEAVY_RAIN(12),
- SHOWERS_RAIN(13),
+ MOSTLY_CLOUDY_DAY(7, "e"),
+ MOSTLY_CLOUDY_NIGHT(8, "e"),
+ CLOUDY(9, "e"),
+ HAZE_FOG_DUST_SMOKE(10, "d"),
+ DRIZZLE(11, "c"),
+ HEAVY_RAIN(12, "c"),
+ SHOWERS_RAIN(13, "c"),
// Scattered showers, day & night.
- SCATTERED_SHOWERS_DAY(14),
- SCATTERED_SHOWERS_NIGHT(15),
+ SCATTERED_SHOWERS_DAY(14, "c"),
+ SCATTERED_SHOWERS_NIGHT(15, "c"),
// Isolated scattered thunderstorms, day & night.
- ISOLATED_SCATTERED_TSTORMS_DAY(16),
- ISOLATED_SCATTERED_TSTORMS_NIGHT(17),
- STRONG_TSTORMS(18),
- BLIZZARD(19),
- BLOWING_SNOW(20),
- FLURRIES(21),
- HEAVY_SNOW(22),
+ ISOLATED_SCATTERED_TSTORMS_DAY(16, "i"),
+ ISOLATED_SCATTERED_TSTORMS_NIGHT(17, "i"),
+ STRONG_TSTORMS(18, "i"),
+ BLIZZARD(19, "j"),
+ BLOWING_SNOW(20, "j"),
+ FLURRIES(21, "h"),
+ HEAVY_SNOW(22, "j"),
// Scattered snow showers, day & night.
- SCATTERED_SNOW_SHOWERS_DAY(23),
- SCATTERED_SNOW_SHOWERS_NIGHT(24),
- SNOW_SHOWERS_SNOW(25),
- MIXED_RAIN_HAIL_RAIN_SLEET(26),
- SLEET_HAIL(27),
- TORNADO(28),
- TROPICAL_STORM_HURRICANE(29),
- WINDY_BREEZY(30),
- WINTRY_MIX_RAIN_SNOW(31);
+ SCATTERED_SNOW_SHOWERS_DAY(23, "h"),
+ SCATTERED_SNOW_SHOWERS_NIGHT(24, "h"),
+ SNOW_SHOWERS_SNOW(25, "g"),
+ MIXED_RAIN_HAIL_RAIN_SLEET(26, "h"),
+ SLEET_HAIL(27, "h"),
+ TORNADO(28, "l"),
+ TROPICAL_STORM_HURRICANE(29, "m"),
+ WINDY_BREEZY(30, "k"),
+ WINTRY_MIX_RAIN_SNOW(31, "h");
companion object {
fun fromInt(value: Int) = values().firstOrNull { it.id == value }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
index 3e39ae9a3fe5..0c46e0784a31 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
+++ b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
@@ -18,4 +18,7 @@ package com.android.systemui.dagger.qualifiers
import javax.inject.Qualifier
/** Annotates a class that is display specific. */
-@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class DisplaySpecific
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+public annotation class DisplaySpecific
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Main.java b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Main.java
index 7b097740ff11..7b097740ff11 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Main.java
+++ b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Main.java
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/UiBackground.java
index 3d37468c322a..3d37468c322a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java
+++ b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/UiBackground.java
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_media_recommendation_bg_gradient.xml b/packages/SystemUI/res-keyguard/drawable/qs_media_recommendation_bg_gradient.xml
deleted file mode 100644
index 495fbb893eac..000000000000
--- a/packages/SystemUI/res-keyguard/drawable/qs_media_recommendation_bg_gradient.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<shape
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <corners android:radius="24dp"/>
- <gradient
- android:angle="0"
- android:startColor="#00000000"
- android:endColor="#ff000000"
- android:type="linear" />
-</shape>
diff --git a/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml b/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml
deleted file mode 100644
index de0a6201cb09..000000000000
--- a/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <!-- gradient from 25% in the center to 100% at edges -->
- <gradient
- android:type="radial"
- android:gradientRadius="40%p"
- android:startColor="#AE000000"
- android:endColor="#00000000" />
-</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/magic_action_button.xml b/packages/SystemUI/res/layout/magic_action_button.xml
index 381d6b17dec5..63fc1e485635 100644
--- a/packages/SystemUI/res/layout/magic_action_button.xml
+++ b/packages/SystemUI/res/layout/magic_action_button.xml
@@ -6,7 +6,7 @@
android:background="@drawable/magic_action_button_background"
android:drawablePadding="@dimen/magic_action_button_drawable_padding"
android:ellipsize="none"
- android:fontFamily="google-sans-flex"
+ android:fontFamily="google-sans-flex-medium"
android:gravity="center"
android:minWidth="0dp"
android:paddingHorizontal="@dimen/magic_action_button_padding_horizontal"
diff --git a/packages/SystemUI/res/layout/media_recommendation_view.xml b/packages/SystemUI/res/layout/media_recommendation_view.xml
deleted file mode 100644
index e63aa211f9f1..000000000000
--- a/packages/SystemUI/res/layout/media_recommendation_view.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<!-- Layout for media recommendation item inside QSPanel carousel -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Album cover -->
- <ImageView
- android:id="@+id/media_cover"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:translationZ="0dp"
- android:scaleType="matrix"
- android:adjustViewBounds="true"
- android:clipToOutline="true"
- android:layerType="hardware"
- android:background="@drawable/bg_smartspace_media_item"/>
-
- <!-- App icon -->
- <com.android.internal.widget.CachingIconView
- android:id="@+id/media_rec_app_icon"
- android:layout_width="@dimen/qs_media_rec_album_icon_size"
- android:layout_height="@dimen/qs_media_rec_album_icon_size"
- android:minWidth="@dimen/qs_media_rec_album_icon_size"
- android:minHeight="@dimen/qs_media_rec_album_icon_size"
- android:layout_marginStart="@dimen/qs_media_info_spacing"
- android:layout_marginTop="@dimen/qs_media_info_spacing"/>
-
- <!-- Artist name -->
- <TextView
- android:id="@+id/media_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/qs_media_info_spacing"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- android:layout_marginBottom="@dimen/qs_media_rec_album_title_bottom_margin"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:singleLine="true"
- android:textSize="12sp"
- android:gravity="top"
- android:layout_gravity="bottom"
- android:importantForAccessibility="no"/>
-
- <!-- Album name -->
- <TextView
- android:id="@+id/media_subtitle"
- android:layout_width="match_parent"
- android:layout_height="@dimen/qs_media_rec_album_subtitle_height"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- android:layout_marginStart="@dimen/qs_media_info_spacing"
- android:layout_marginBottom="@dimen/qs_media_info_spacing"
- android:fontFamily="@*android:string/config_headlineFontFamily"
- android:singleLine="true"
- android:textSize="11sp"
- android:gravity="center_vertical"
- android:layout_gravity="bottom"
- android:importantForAccessibility="no"/>
-
- <!-- Seek Bar -->
- <SeekBar
- android:id="@+id/media_progress_bar"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_gravity="bottom"
- android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
- android:thumb="@android:color/transparent"
- android:splitTrack="false"
- android:clickable="false"
- android:progressTint="?android:attr/textColorPrimary"
- android:progressBackgroundTint="?android:attr/textColorTertiary"
- android:paddingTop="5dp"
- android:paddingBottom="5dp"
- android:paddingStart="0dp"
- android:paddingEnd="0dp"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- android:layout_marginStart="@dimen/qs_media_info_spacing"
- android:layout_marginBottom="@dimen/qs_media_info_spacing"/>
-</merge> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_recommendations.xml b/packages/SystemUI/res/layout/media_recommendations.xml
deleted file mode 100644
index 65fc19c5b2a4..000000000000
--- a/packages/SystemUI/res/layout/media_recommendations.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<!-- Layout for media recommendations inside QSPanel carousel -->
-<com.android.systemui.util.animation.TransitionLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/media_recommendations_updated"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:forceHasOverlappingRendering="false"
- android:background="@drawable/qs_media_background"
- android:theme="@style/MediaPlayer">
-
- <!-- This view just ensures the full media player is a certain height. -->
- <View
- android:id="@+id/sizing_view"
- android:layout_width="match_parent"
- android:layout_height="@dimen/qs_media_session_height_expanded" />
-
- <TextView
- android:id="@+id/media_rec_title"
- style="@style/MediaPlayer.Recommendation.Header"
- android:text="@string/controls_media_smartspace_rec_header"/>
-
- <FrameLayout
- android:id="@+id/media_cover1_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- >
-
- <include
- layout="@layout/media_recommendation_view"/>
-
- </FrameLayout>
-
-
- <FrameLayout
- android:id="@+id/media_cover2_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- >
-
- <include
- layout="@layout/media_recommendation_view"/>
-
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/media_cover3_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- >
-
- <include
- layout="@layout/media_recommendation_view"/>
-
- </FrameLayout>
-
- <include
- layout="@layout/media_long_press_menu" />
-
-</com.android.systemui.util.animation.TransitionLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index f41eaec8e18b..a1fa54cf592d 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -40,7 +40,7 @@
android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
android:clipChildren="false"
app:layout_constraintBottom_toTopOf="@id/volume_dialog_main_slider_container"
- app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
+ app:layout_constraintEnd_toEndOf="@id/volume_dialog_background"
app:layout_constraintHeight_default="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -70,9 +70,9 @@
android:layout_marginTop="@dimen/volume_dialog_components_spacing"
android:clipChildren="false"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
+ app:layout_constraintEnd_toEndOf="@id/volume_dialog_background"
app:layout_constraintHeight_default="wrap"
- app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
+ app:layout_constraintStart_toStartOf="@id/volume_dialog_background"
app:layout_constraintTop_toBottomOf="@id/volume_dialog_main_slider_container"
app:layout_constraintVertical_bias="0"
app:layout_constraintWidth_default="wrap">
diff --git a/packages/SystemUI/res/layout/volume_dialog_top_section.xml b/packages/SystemUI/res/layout/volume_dialog_top_section.xml
index 29f52480bfe0..b7455471d9a6 100644
--- a/packages/SystemUI/res/layout/volume_dialog_top_section.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_top_section.xml
@@ -22,7 +22,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="center"
- android:paddingEnd="@dimen/volume_dialog_ringer_drawer_diff_end_margin"
+ android:paddingEnd="@dimen/volume_dialog_buttons_margin"
app:layoutDescription="@xml/volume_dialog_ringer_drawer_motion_scene">
<View
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 4179d8a89dee..cbec8c2e0b82 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Gekoppel aan <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Gekoppel aan <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Vou groep uit."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Voeg toestel by groep."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Verwyder toestel uit groep."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Maak app oop."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nie gekoppel nie."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Swerwing"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Gehoortoestelle"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Skakel tans aan …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Kan nie helderheid verstel nie omdat dit deur die boonste app beheer word"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outodraai"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Voeg by posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisie is ongeldig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Teël is bygevoeg"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Teël is verwyder"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Stel alle teëls terug?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Kitsinstellingsteëls sal na die toestel se oorspronklike instellings teruggestel word"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a92a1416fd2c..655f06037922 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ከ<xliff:g id="BLUETOOTH">%s</xliff:g> ጋር ተገናኝቷል።"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"ከ<xliff:g id="CAST">%s</xliff:g> ጋር ተገናኝቷል።"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ቡድንን ዘርጋ።"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"መሣሪያን ወደ ቡድን አክል።"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"መሣሪያን ከቡድን ላይ አስወግድ።"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"መተግበሪያ ክፈት።"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"አልተገናኘም።"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"በማዛወር ላይ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ግቤት"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"መስሚያ አጋዥ መሣሪያዎች"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"በማብራት ላይ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ከላይ ባለው መተግበሪያ ቁጥጥር እየተደረገበት ስለሆነ ብሩህነትን ማስተካከል አልተቻለም"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ቦታ አክል"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"አቀማመጡ ተቀባይነት የለውም።"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"የ<xliff:g id="POSITION">%1$d</xliff:g> አቀማመጥ"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ሰቅ ታክሏል"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ሰቅ ተወግዷል"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ያልታወቀ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ሁሉም ሰቆች ዳግም ይጀምሩ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ሁሉም የፈጣን ቅንብሮች ሰቆች ወደ የመሣሪያው የመጀመሪያ ቅንብሮች ዳግም ይጀምራሉ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>፣ <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 13f3fd8d4e1b..b2d71da5b61d 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"متصل بـ <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"تم الاتصال بـ <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"سيتم توسيع المجموعة."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"إضافة الجهاز إلى المجموعة"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"إزالة الجهاز من المجموعة"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"سيتم فتح التطبيق."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"غير متصل."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"التجوال"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"الإدخال"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعات الأذن الطبية"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"جارٍ التفعيل…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"لا يمكن ضبط مستوى السطوع لأنّ التطبيق العلوي يتحكّم فيه"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"التدوير التلقائي"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"التدوير التلقائي للشاشة"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"الموقع الجغرافي"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"الإضافة إلى الموضع <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"الموضِع غير صالح."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"الموضع: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"تمت إضافة البطاقة."</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"تمت إزالة البطاقة."</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 067649cdea65..6aa9d66ab48f 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>ত সংযোগ হ’ল।"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"গোট বিস্তাৰ কৰক।"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"গোটত ডিভাইচ যোগ দিয়ক।"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"গোটৰ পৰা ডিভাইচ আঁতৰাওক।"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"এপ্লিকেশ্বনটো খোলক।"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"সংযোগ হৈ থকা নাই।"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ৰ\'মিং"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"শ্ৰৱণ যন্ত্ৰ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"অন কৰি থকা হৈছে…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"উজ্জ্বলতা মিলাব নোৱাৰি কাৰণ সেয়া শীৰ্ষৰ এপটোৱে নিয়ন্ত্ৰণ কৰি আছে"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"অৱস্থান"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থানত যোগ দিয়ক"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"স্থান অমান্য।"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থান"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ দিয়া হৈছে"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল আঁতৰোৱা হৈছে"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিঙৰ সম্পাদক।"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজ্ঞাত"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"আটাইবোৰ টাইল ৰিছেট কৰিবনে?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"আটাইবোৰ ক্ষিপ্ৰ ছেটিঙৰ টাইল ডিভাইচৰ মূল ছেটিংছলৈ ৰিছেট হ’ব"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9df9923b115b..b87432f5d342 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> üzərindən qoşuldu."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> cihazına qoşulub."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Qrupu genişləndirin."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Qrupa cihaz əlavə edin."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Cihazı qrupdan silin."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Tətbiqi açın."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Qoşulu deyil."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Rouminq"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eşitmə aparatları"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiv edilir..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Yuxarıdakı tətbiq tərəfindən idarə olunduğu üçün parlaqlığı tənzimləmək mümkün deyil"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtodönüş"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranın avtomatik dönməsi"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Məkan"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə əlavə edin"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Mövqe yanlışdır."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Mozaik əlavə edilib"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Mozaik silinib"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Naməlum"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Bütün mozaiklər sıfırlansın?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Bütün Sürətli Ayarlar mozaiki cihazın orijinal ayarlarına sıfırlanacaq"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6ab7bf1d10ac..a875e7361335 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicija je nevažeća."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite da resetujete sve pločice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brzih podešavanja će se resetovati na prvobitna podešavanja uređaja"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 94f950720a20..75d0a44f38a1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Падлучаны да <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Ёсць падключэнне да <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Разгарнуць групу."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Дадаць прыладу ў групу."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Выдаліць прыладу з групы."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Адкрыць праграму."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Няма падключэння."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роўмінг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Увод"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слыхавыя апараты"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Уключэнне…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не ўдаецца адрэгуляваць яркасць, бо яна кантралюецца верхняй праграмай"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Няправільнае месца."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Пазіцыя <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плітка дададзена"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плітка выдалена"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 4615e60730f2..4f3d64124e04 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Има връзка с <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Установена е връзка с/ъс <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Разгъване на групата."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Добавяне на устройството към групата."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Премахване на устройството от групата."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Отваряне на приложението."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Няма връзка."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Вход"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухови апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включва се..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Яркостта не може да се коригира, защото се контролира от приложението на екрана"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авт. ориентация"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавяне към позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Невалидна позиция."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панелът е добавен"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панелът е премахнат"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор за бързи настройки."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 6247bf14f726..3fd699db612f 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>এ সংযুক্ত হয়ে আছে।"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> এর সাথে সংযুক্ত৷"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"গ্রুপ বড় করুন।"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"গ্রুপে ডিভাইস যোগ করুন।"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"গ্রুপ থেকে ডিভাইস সরিয়ে দিন।"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"অ্যাপ্লিকেশন খুলুন।"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"সংযুক্ত নয়৷"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"রোমিং"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"হিয়ারিং এড"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"চালু করা হচ্ছে…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"উজ্জ্বলতা অ্যাডজাস্ট করা যাচ্ছে না কারণ এটি সেরা অ্যাপের মাধ্যমে কন্ট্রোল করা হচ্ছে"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"নিজে থেকে ঘুরবে"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"অটো-রোটেট স্ক্রিন"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"লোকেশন"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>-এ যোগ করুন"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"পজিশন সঠিক নয়।"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ করা হয়েছে"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল সরানো হয়েছে"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজানা"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"সব টাইল রিসেট করবেন?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"সব কুইক সেটিংস টাইল, ডিভাইসের আসল সেটিংসে রিসেট হয়ে যাবে"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 75f3f08356c2..0b5af1771614 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezan na <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Povezan na <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Proširivanje grupe."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Dodavanje uređaja u grupu."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Uklanjanje uređaja iz grupe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otvaranje aplikacije."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ulaz"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Nije moguće podesiti osvijetljenost jer njome upravlja gornja aplikacija"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko rotiranje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nevažeći položaj."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vratiti sve kartice na zadano?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve kartice Brze postavke će se vratiti na originalne postavke uređaja"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 19b299f14824..0225d2b27ca8 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"S\'ha connectat a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Està connectat amb <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Desplega el grup."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Afegeix el dispositiu al grup."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Suprimeix el dispositiu del grup."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Obre l\'aplicació."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Sense connexió."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Itinerància"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiòfons"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"S\'està activant…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"No es pot ajustar la brillantor perquè està controlada per l\'aplicació superior"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Gira automàticament"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Gira la pantalla automàticament"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Afegeix a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"La posició no és vàlida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"El mosaic s\'ha afegit"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"El mosaic s\'ha suprimit"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconegut"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vols restablir totes les icones?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Totes les icones de configuració ràpida es restabliran a les opcions originals del dispositiu"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 51dfa2ec680d..8a6980e355c0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Připojeno k zařízení <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Jste připojeni k zařízení <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Rozbalit skupinu."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Přidat zařízení do skupiny."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Odstranit zařízení ze skupiny."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otevřít aplikaci."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nepřipojeno."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Naslouchátka"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapínání…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Jas nelze upravit, protože ho řídí hlavní aplikace"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. otáčení"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčení obrazovky"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Přidat dlaždici na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozice není platná."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dlaždice byla přidána"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Dlaždice byla odstraněna"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznámé"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetovat všechny dlaždice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všechny dlaždice Rychlého nastavení se resetují do původní konfigurace zařízení"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ad6633e2cfaf..60c5c1c5e1c0 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Forbundet med <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Forbundet til <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Udvid gruppe."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Føj enhed til gruppe."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Fjern enhed fra gruppe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Åbn app."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ikke tilsluttet."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverer…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Lysstyrken kan ikke justeres, fordi den styres af den øverste app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Roter automatisk"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Roter skærmen automatisk"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokation"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Føj til lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen er ugyldig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Feltet blev tilføjet"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Feltet blev fjernet"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukendt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du nulstille alle handlingsfelter?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle handlingsfelter i kvikmenuen nulstilles til enhedens oprindelige indstillinger"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8bc38157f90a..66b60b18cdae 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Mit <xliff:g id="BLUETOOTH">%s</xliff:g> verbunden"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Verbunden mit <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Gruppe erweitern."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Gerät zu Gruppe hinzufügen."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Gerät aus Gruppe entfernen."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Anwendung öffnen."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nicht verbunden"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Eingabe"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörgerät"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Wird aktiviert…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Die Helligkeit kann nicht angepasst werden, weil sie von der obersten App gesteuert wird"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. drehen"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Standort"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Zur Position <xliff:g id="POSITION">%1$d</xliff:g> hinzufügen"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position ist ungültig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ansicht hinzugefügt"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ansicht entfernt"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unbekannt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Alle Kacheln zurücksetzen?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Schnelleinstellungen-Kacheln werden auf die Standardeinstellungen des Geräts zurückgesetzt"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dade080e2624..639aee2d038e 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Συνδέθηκε στο <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Συνδέθηκε σε <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Αναπτύξτε την ομάδα."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Προσθήκη συσκευής στην ομάδα."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Κατάργηση συσκευής από την ομάδα."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Ανοίξτε την εφαρμογή."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Μη συνδεδεμένο"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Περιαγωγή"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Είσοδος"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Βοηθήματα ακοής"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ενεργοποίηση…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Δεν είναι δυνατή η προσαρμογή της φωτεινότητας, επειδή ελέγχεται από την εφαρμογή στην κορυφή"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Αυτόματη περιστροφή"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Αυτόματη περιστροφή οθόνης"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Τοποθεσία"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Προσθήκη στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Μη έγκυρη θέση."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Το πλακίδιο προστέθηκε"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Το πλακίδιο καταργήθηκε"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index fb251ddc47a2..62441c8682f3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expand group."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Add device to group."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remove device from group."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Open application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Can\'t adjust brightness because it\'s being controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 54ef0cc72da1..69aca1fb223e 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -423,12 +423,9 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
- <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
- <skip />
- <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
- <skip />
- <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
- <skip />
+ <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Surroundings"</string>
+ <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Left surroundings"</string>
+ <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Right surroundings"</string>
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
@@ -1003,6 +1000,7 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tile already added"</string>
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index fb251ddc47a2..62441c8682f3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expand group."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Add device to group."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remove device from group."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Open application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Can\'t adjust brightness because it\'s being controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index fb251ddc47a2..62441c8682f3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expand group."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Add device to group."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remove device from group."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Open application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Can\'t adjust brightness because it\'s being controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tile added"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tile removed"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 371638b311c7..840afd45cdf2 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expandir grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Agregar el dispositivo al grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Quitar el dispositivo del grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abrir aplicación."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"No conectado"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"La app superior controla el brillo, por lo que no se puede ajustar"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar la pantalla automáticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Agregar a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Se agregó la tarjeta"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Se quitó la tarjeta"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de Configuración rápida"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b02ab301bf9c..177f298d0121 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Mostrar grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Añade un dispositivo al grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Quita un dispositivo del grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abrir aplicación."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"No conectado."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"No se puede ajustar el brillo porque la aplicación superior lo está controlando"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar pantalla automáticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Añadir a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Recuadro añadido"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Recuadro quitado"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"¿Borrar todos los recuadros?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos los recuadros de ajustes rápidos se restablecerán a los ajustes originales del dispositivo"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 578ca4d663c3..be021fc96f9d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ühendatud: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Ühendatud ülekandega <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Grupi laiendamine."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Seadme lisamine gruppi."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Seadme eemaldamine grupist."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Rakenduse avamine."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ühendus puudub."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Rändlus"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sisend"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuuldeaparaadid"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Sisselülitamine …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Heledust ei saa reguleerida, kuna seda juhib ülemine rakendus"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. pööramine"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Kuva automaatne pööramine"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Asukoht"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Sobimatu asukoht."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Asend <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Paan on lisatud"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Paan on eemaldatud"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index c6b8f5641f56..edcc17225ace 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> gailura konektatuta."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Hona konektatuta: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Zabaldu taldea."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Gehitu gailua taldera"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Kendu gailua taldetik."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Ireki aplikazioa."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Konektatu gabe."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Ibiltaritza"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sarrera"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audifonoak"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktibatzen…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Ezin da argitasuna doitu goiko aplikazioak kontrolatzen duelako"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Biratze automatikoa"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Biratu pantaila automatikoki"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Kokapena"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Gehitu <xliff:g id="POSITION">%1$d</xliff:g>garren lekuan"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kokapenak ez du balio."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>garren lekua"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Gehitu da lauza"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kendu da lauza"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 6f4d1bc35a8c..f1f6a14568a5 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"به <xliff:g id="BLUETOOTH">%s</xliff:g> متصل شد."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"به <xliff:g id="CAST">%s</xliff:g> متصل شد."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"گروه را از هم باز می‌کند."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"افزودن دستگاه به گروه."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"حذف دستگاه از گروه."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"برنامه را باز می‌کند."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"متصل نیست."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"فراگردی"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ورودی"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سمعک"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"روشن کردن…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"نمی‌توان روشنایی را تنظیم کرد زیرا برنامه بالایی آن را کنترل می‌کند"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"چرخش خودکار"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"چرخش خودکار صفحه‌نمایش"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"مکان"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"افزودن به موقعیت <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"موقعیت نامعتبر است."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"کاشی اضافه شد"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"کاشی حذف شد"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ویرایشگر تنظیمات سریع."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامشخص"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"همه کاشی‌ها بازنشانی شود؟"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"همه کاشی‌های «تنظیمات فوری» به تنظیمات اصلی دستگاه بازنشانی خواهد شد"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>، <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 527a29288bcc..747659956dbf 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -254,10 +254,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Yhteys: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Yhdistetty kohteeseen <xliff:g id="CAST">%s</xliff:g>"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Laajenna ryhmä."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Lisää laite ryhmään."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Poista laite ryhmästä."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Avaa sovellus."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ei yhteyttä."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -335,8 +333,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Syöttölaite"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuulolaitteet"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Otetaan käyttöön…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Kirkkautta ei voi säätää, koska ensisijainen sovellus ohjaa sitä"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automaattinen kääntö"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Käännä näyttöä automaattisesti."</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Sijainti"</string>
@@ -1008,6 +1005,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisää paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Virheellinen sijainti."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kiekko lisätty"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kiekko poistettu"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string>
@@ -1576,6 +1575,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tuntematon"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Nollataanko kaikki laatat?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Kaikki pika-asetuslaatat palautetaan laitteen alkuperäisiin asetuksiin"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 6a2d7c809927..e22f306b0d57 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Développer le groupe."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Ajouter un appareil au groupe."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Retirer l\'appareil du groupe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Ouvrir l\'appli."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Non connecté"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Itinérance"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Prothèses auditives"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation en cours…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Impossible de régler la luminosité, car elle est contrôlée par l\'appli principale"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position incorrecte."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tuile ajoutée"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tuile retirée"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de paramètres rapides."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser toutes les tuiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toutes les tuiles des paramètres rapides seront réinitialisées aux paramètres par défaut de l\'appareil."</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index e9d3c487009a..487c566bf50f 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -68,7 +68,7 @@
</string-array>
<string-array name="tile_states_bt">
<item msgid="5330252067413512277">"Non disponible"</item>
- <item msgid="5315121904534729843">"Désactivée"</item>
+ <item msgid="5315121904534729843">"Désactivé"</item>
<item msgid="503679232285959074">"Activé"</item>
</string-array>
<string-array name="tile_states_airplane">
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 62916e8dff07..cceab1c3689b 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Développer le groupe."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Ajouter l\'appareil au groupe."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Supprimer l\'appareil du groupe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Ouvrir l\'application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Non connecté"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Itinérance"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Appareils auditifs"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Impossible d\'ajuster la luminosité, car celle-ci est contrôlée par l\'appli principale"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Emplacement non valide."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloc ajouté"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloc supprimé"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur Réglages rapides"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser tous les blocs ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tous les blocs \"Réglages rapides\" seront réinitialisés aux paramètres d\'origine de l\'appareil"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 87980c89d949..f54a634eaa18 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Dispositivo conectado: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Despregar o grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Engadir o dispositivo ao grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Quitar o dispositivo do grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abrir a aplicación."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Non conectada"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Itinerancia"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiófonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Non se pode axustar o brillo porque o controla a aplicación principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localización"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engadir á posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición non válida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Engadiuse a tarxeta"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Quitouse a tarxeta"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Categoría descoñecida"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Queres restablecer todos os atallos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Restablecerase a configuración orixinal do dispositivo para todos os atallos de Configuración rápida"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index e61d4e1fddf1..1830b347f829 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1006,6 +1006,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"જગ્યા પર <xliff:g id="POSITION">%1$d</xliff:g> ઉમેરો"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"સ્થિતિ અમાન્ય છે."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"જગ્યા <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ટાઇલ ઉમેરી"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ટાઇલ કાઢી નાખી"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ એડિટર."</string>
@@ -1574,6 +1576,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"અજાણ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"તમામ ટાઇલ રીસેટ કરીએ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"તમામ ઝડપી સેટિંગ ટાઇલને ડિવાઇસના ઑરિજિનલ સેટિંગ પર રીસેટ કરવામાં આવશે"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0dfbb4cb58b6..644980062f9f 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> से कनेक्ट किया गया."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> से कनेक्ट है."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ग्रुप को बड़ा करें."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"डिवाइस को ग्रुप में जोड़ें."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"डिवाइस को ग्रुप से हटाएं."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ऐप्लिकेशन खोलें."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"कनेक्ट नहीं है."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"रोमिंग"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"कान की मशीनें"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ब्लूटूथ चालू हो रहा है…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"स्क्रीन की रोशनी को अडजस्ट नहीं किया जा सकता, क्योंकि इसे टॉप ऐप्लिकेशन कंट्रोल कर रहा है"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रीन का अपने-आप दिशा बदलना (ऑटो-रोटेट)"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"जगह की जानकारी"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर जोड़ें"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"मौजूदा जगह अमान्य है."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"टाइल की पोज़िशन <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोड़ी गई"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाई गई"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 4dba93076218..7db95fe316ce 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Spojen na <xliff:g id="BLUETOOTH">%s</xliff:g> ."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani ste sa sljedećim uređajem: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Proširite grupu."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Dodajte uređaj u grupu."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Uklonite uređaj iz grupe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otvorite aplikaciju."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušna pomagala"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Svjetlina se ne može prilagoditi jer njome upravlja aplikacija pri vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko zakretanje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj nije važeći."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite li poništiti sve pločice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brze postavke vratit će se na izvorne postavke uređaja"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 891cf28a2582..906ce54f33fd 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Csatlakoztatva a következőhöz: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Csatlakozva a következőhöz: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Csoport kibontása."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Eszköz hozzáadása csoporthoz."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Eszköz eltávolítása csoportból."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Alkalmazás megnyitása."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nincs csatlakozva."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Bevitel"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hallókészülék"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Bekapcsolás…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Nem lehet módosítani a fényerőt, mert a felső alkalmazás vezérli"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatikus elforgatás"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatikus képernyőforgatás"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Tartózkodási hely"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Hozzáadás a következő pozícióhoz: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Érvénytelen pozíció."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. hely"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kártya hozzáadva"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kártya eltávolítva"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Gyorsbeállítások szerkesztője"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f231822daeb9..57a822e138c2 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Միացված է <xliff:g id="BLUETOOTH">%s</xliff:g>-ին:"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Միացված է <xliff:g id="CAST">%s</xliff:g>-ին:"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Ծավալել խումբը։"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Սարքը ավելացնել խմբին։"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Հեռացնել սարքը խմբից։"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Բացել հավելվածը։"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Միացված չէ:"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Ռոումինգ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Մուտքագրում"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Լսողական սարք"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Միացում…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Հնարավոր չէ կարգավորել պայծառությունը, քանի որ այն կառավարվում է գլխավոր հավելվածի կողմից"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ինքնապտտում"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ավտոմատ պտտել էկրանը"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Տեղորոշում"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ավելացնել դիրք <xliff:g id="POSITION">%1$d</xliff:g>-ում"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Դիրքն անվավեր է։"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Սալիկն ավելացվեց"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Սալիկը հեռացվեց"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Արագ կարգավորումների խմբագրիչ:"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Անհայտ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Զրոյացնե՞լ բոլոր սալիկները"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Արագ կարգավորումների բոլոր սալիկները կզրոյացվեն սարքի սկզբնական կարգավորումների համաձայն։"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index e0e69a9555af..2d38c8fa8e7a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Terhubung 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_expand_group" msgid="521237935987978624">"Luaskan grup."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Tambahkan perangkat ke grup."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Hapus perangkat dari grup."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Buka aplikasi."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak terhubung."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu dengar"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Mengaktifkan…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Tidak dapat menyesuaikan kecerahan karena sedang dikontrol oleh aplikasi atas"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Putar Otomatis"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Putar layar otomatis"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan ke posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisi tidak valid."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartu ditambahkan"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartu dihapus"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset semua kartu?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua kartu Setelan Cepat akan direset ke setelan asli perangkat"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index faff4c59f275..5c37bdb40161 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tengt við <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Tengt við <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Stækka hóp."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Bæta tæki við hóp."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Fjarlægja tæki úr hóp."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Opna forrit."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Engin tenging."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Reiki"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Inntak"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Heyrnartæki"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Kveikir…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Ekki er hægt að breyta birtustiginu vegna þess að efsta forritið stjórnar því"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Sjálfvirkur snúningur"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Snúa skjá sjálfkrafa"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Staðsetning"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bæta við í stöðu <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Staða ógild."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Staða <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Reit bætt við"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Reitur fjarlægður"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Flýtistillingaritill."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Óþekkt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Endurstilla alla reiti?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Allir flýtistillingareitir munu endurstillast á upprunalegar stillingar tækisins"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index e6f5dee09ce3..a21b6dbac247 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Aggiungi alla posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posizione non valida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Riquadro aggiunto"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Riquadro rimosso"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor di impostazioni rapide."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8e2df321d0fd..936b10e520d5 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1006,6 +1006,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"הוספה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"המיקום לא תקין."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"הלחצן נוסף"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"הלחצן הוסר"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string>
@@ -1574,6 +1576,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"לא ידוע"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"לאפס את כל הלחצנים?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"כל הלחצנים ב\'הגדרות מהירות\' יאופסו להגדרות המקוריות של המכשיר"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"‫<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 5daa645ec0a8..d5ecfe538b89 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> に追加"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置が無効です。"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"タイルを追加しました"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"タイルを削除しました"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"クイック設定エディタ"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 68f48b00f3ca..2e3dc98eb153 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"დაკავშირებულია <xliff:g id="BLUETOOTH">%s</xliff:g>-თან."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"დაკავშირებულია მოწყობილობასთან: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ჯგუფის გაფართოება."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"მოწყობილობის ჯგუფში დამატება."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"მოწყობილობის ჯგუფიდან ამოშლა."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"აპლიკაციის გახსნა."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"არ არის დაკავშირებული."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"როუმინგი"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"შეყვანა"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"სმენის მოწყობილობები"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ირთვება…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"სიკაშკაშის კორექტირება ვერ ხერხდება, რადგან ის იმართება გახსნილი აპის მიერ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ავტოროტაცია"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ეკრანის ავტომატური შეტრიალება"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"მდებარეობა"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"დამატება პოზიციაზე <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"პოზიცია არასწორია."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"მოზაიკის ფილა დაემატა"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"მოზაიკის ფილა ამოიშალა"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"სწრაფი პარამეტრების რედაქტორი."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"უცნობი"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"გსურთ ყველა ფილის გადაყენება?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"სწრაფი პარამეტრების ყველა ფილა გადაყენდება მოწყობილობის ორიგინალ პარამეტრებზე"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 1ecc7438b088..1c4d31a6b758 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> қосылған."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> трансляциясына қосылды."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Топты жайыңыз."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Құрылғыны топқа қосады."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Құрылғыны топтан өшіреді."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Қолданбаны ашыңыз."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Жалғанбаған."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Кіріс"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Есту аппараттары"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Қосылып жатыр…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Жарықтықты реттеу мүмкін емес, себебі ол жетекші қолданба арқылы басқарылады."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматты түрде бұру"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматты айналатын экран"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локация"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> орнына қосу"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Орын жарамсыз."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> орны"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Бөлшек қосылды."</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Бөлшек өшірілді."</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгісіз"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Барлық бөлшекті бастапқы күйге қайтару керек пе?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Барлық \"Жылдам параметрлер\" бөлшегі құрылғының бастапқы параметрлеріне қайтарылады."</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 8c5ea900a97a..8b3bfcc1d30b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"បាន​ភ្ជាប់​ទៅ <xliff:g id="BLUETOOTH">%s</xliff:g> ។"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"បានភ្ជាប់ទៅ <xliff:g id="CAST">%s</xliff:g>"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ពង្រីកក្រុម។"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"បញ្ចូលឧបករណ៍ទៅក្រុម។"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ដកឧបករណ៍ចេញពីក្រុម។"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"បើកកម្មវិធី។"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"មិន​បាន​តភ្ជាប់​។"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"រ៉ូ​មីង"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"បញ្ចូល"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"កំពុង​បើក..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"មិនអាចកែតម្រូវកម្រិតពន្លឺបានទេ ដោយសារវាកំពុងស្ថិតក្រោមការគ្រប់គ្រងរបស់កម្មវិធីខាងលើគេ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"បង្វិល​ស្វ័យ​ប្រវត្តិ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ទី​តាំង​"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"បញ្ចូលទៅ​ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ទីតាំងគ្មានសុពលភាព។"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"បានបញ្ចូលប្រអប់"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"បាន​ផ្លាស់ទី​ប្រអប់"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 7c785d95ae38..50f8c60537ba 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ಗುಂಪು ವಿಸ್ತರಿಸಿ."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ಸಾಧನವನ್ನು ಗುಂಪಿಗೆ ಸೇರಿಸಿ."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ಸಾಧನವನ್ನು ಗುಂಪಿನಿಂದ ತೆಗೆದುಹಾಕಿ."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ರೋಮಿಂಗ್"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ಇನ್‌ಪುಟ್"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ಆನ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ಬ್ರೈಟ್‌ನೆಸ್ ಅನ್ನು ಹೊಂದಾಣಿಕೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ, ಏಕೆಂದರೆ ಅದನ್ನು ಟಾಪ್ ಆ್ಯಪ್ ನಿಯಂತ್ರಿಸುತ್ತಿದೆ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ಸ್ವಯಂ-ತಿರುಗುವಿಕೆ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ಸ್ಥಳ"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ಸ್ಥಾನಕ್ಕೆ ಸೇರಿಸಿ"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ಸ್ಥಾನವು ಅಮಾನ್ಯವಾಗಿದೆ."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ಸ್ಥಾನ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ಟೈಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ಟೈಲ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳ ಎಡಿಟರ್."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ಅಪರಿಚಿತ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ಎಲ್ಲಾ ಟೈಲ್‌ಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ಎಲ್ಲಾ ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಟೈಲ್‌ಗಳನ್ನು ಸಾಧನದ ಮೂಲ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index b3c21b11bf28..7342f32f116e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>에 연결되었습니다."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>에 연결됨"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"그룹을 펼칩니다."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"기기를 그룹에 추가합니다."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"그룹에서 기기를 삭제합니다."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"애플리케이션을 엽니다."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"연결되지 않았습니다."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"로밍"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"입력"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"보청기"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"켜는 중..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"상위 앱에서 밝기를 제어하고 있으므로 밝기를 조절할 수 없습니다."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"자동 회전"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"화면 자동 회전"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"위치"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> 위치에 추가"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"위치가 잘못되었습니다."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> 위치"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"타일 추가됨"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"타일 삭제됨"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"알 수 없음"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"모든 타일을 재설정하시겠습니까?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"모든 빠른 설정 타일이 기기의 원래 설정으로 재설정됩니다."</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 9aedbb5e0569..f21ee1a401b7 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> менен туташкан."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> менен туташты."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Топту жайып көрсөтүү."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Түзмөктү топко кошуңуз."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Түзмөктү топтон алып салыңыз."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Колдонмону ачуу."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Интернет жок."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Киргизүү"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Угуу аппараттары"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Күйгүзүлүүдө…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Жарыктыкты тууралоого болбойт, анткени аны жогорку колдонмо көзөмөлдөйт"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авто буруу"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Экранды авто буруу"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Жайгашкан жер"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>-позицияга кошуу"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Абал жараксыз."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>-позиция"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Карта кошулду"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Карта өчүрүлдү"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ыкчам параметрлер түзөткүчү."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгисиз"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык параметрлерди кайра коесузбу?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык ыкчам параметрлер түзмөктүн баштапкы маанилерине кайтарылат"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 47b32354df40..4c778d1ac869 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ເຊື່ອມ​ຕໍ່​ຫາ <xliff:g id="BLUETOOTH">%s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"ເຊື່ອມຕໍ່ຫາ <xliff:g id="CAST">%s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ຂະຫຍາຍກຸ່ມ."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ເພີ່ມອຸປະກອນໃສ່ໃນກຸ່ມ."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ລຶບອຸປະກອນອອກຈາກກຸ່ມ."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ເປີດແອັບພລິເຄຊັນ."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"ບໍ່ໄດ້ເຊື່ອມຕໍ່."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ໂຣມມິງ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ການປ້ອນຂໍ້ມູນ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ເຄື່ອງຊ່ວຍຟັງ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ກຳລັງເປີດ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ບໍ່ສາມາດປັບຄວາມສະຫວ່າງໄດ້ເນື່ອງຈາກຄວບຄຸມໂດຍແອັບທາງເທິງ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ໝຸນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ສະຖານທີ່"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ເພີ່ມໃສ່ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ຕຳແໜ່ງບໍ່ຖືກຕ້ອງ."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ເພີ່ມແຜ່ນແລ້ວ"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ລຶບແຜ່ນແລ້ວ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ບໍ່ຮູ້ຈັກ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ຣີເຊັດແຜ່ນທັງໝົດບໍ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ແຜ່ນການຕັ້ງຄ່າດ່ວນທັງໝົດຈະຣີເຊັດເປັນການຕັ້ງຄ່າແບບເກົ່າຂອງອຸປະກອນ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5971e730ac74..f387a4ed4178 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Prisijungta prie „<xliff:g id="BLUETOOTH">%s</xliff:g>“."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Prisijungta prie <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Išskleisti grupę."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Pridėti įrenginį prie grupės."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Pašalinti įrenginį iš grupės."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Atidaryti programą."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Neprijungta."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Tarptinklinis ryšys"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Įvestis"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Klausos aparatai"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Įjungiama…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Negalima koreguoti šviesumo, nes jį valdo viršuje esanti programa"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatinis pasukimas"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatiškai sukti ekraną"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vietovė"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridėkite <xliff:g id="POSITION">%1$d</xliff:g> pozicijoje"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Padėtis netinkama."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> pozicija"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Išklotinė pridėta"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Išklotinė pašalinta"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sparčiųjų nustatymų redagavimo priemonė."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index bb8d7028fce4..fd549219134f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ir izveidots savienojum ar <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Savienots ar ierīci <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Izvērst grupu."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Pievienot ierīci grupai."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Noņemt ierīci no grupas."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Atvērt lietojumprogrammu."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Savienojums nav izveidots."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Viesabonēšana"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ievade"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Dzirdes aparāti"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Notiek ieslēgšana…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Nevar mainīt spilgtumu, jo to kontrolē lietotne augšpusē"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automātiska pagriešana"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automātiska ekrāna pagriešana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Atrašanās vieta"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pievienot elementu pozīcijā numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nederīga pozīcija."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozīcija numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Elements ir pievienots"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Elements ir noņemts"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nezināma"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vai atiestatīt visus elementus?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Visiem ātro iestatījumu elementiem tiks atiestatīti sākotnējie iestatījumi"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 189390ff9edc..2afe93ea7aae 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Поврзано со <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Поврзано со <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Проширете ја групата."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Додај го уредот во групата."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Отстрани го уредот од групата."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Отворете ја апликацијата."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Не е поврзана"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роаминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Влез"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни помагала"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Се вклучува…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не може да се приспособи осветленоста бидејќи е контролирана од горната апликација"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додавање на позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позицијата е погрешна."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Додадена е плочка"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Отстранета е плочка"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Да се ресетираат сите плочки?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Сите плочки на „Брзи поставки“ ќе се ресетираат на првичните поставки на уредот"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 7e4282f0f70f..48d07cb2ae28 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> എന്ന സ്ഥാനത്തേക്ക് ചേർക്കുക"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"സ്ഥാനം അസാധുവാണ്."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ടൈൽ ചേർത്തു"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ടൈൽ നീക്കം ചെയ്‌തു"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ദ്രുത ക്രമീകരണ എഡിറ്റർ."</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"അജ്ഞാതം"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"എല്ലാ ടൈലുകളും റീസെറ്റ് ചെയ്യണോ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"എല്ലാ ദ്രുത ക്രമീകരണ ടൈലുകളും ഉപകരണത്തിന്റെ ഒറിജിനൽ ക്രമീകരണത്തിലേക്ക് റീസെറ്റ് ചെയ്യും"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c6ab2c5a5368..c7fb7da28ead 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>-тай холбогдсон."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>-д холбогдсон."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Бүлгийг дэлгэнэ үү."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Бүлэгт төхөөрөмж нэмнэ."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Бүлгээс төхөөрөмж хасна."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Аппликейшныг нээнэ үү."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Холбогдоогүй."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Сонсголын төхөөрөмж"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Асааж байна…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Гэрэлтүүлгийг давуу эрхтэй аппаас хянаж байгаа тул тохируулах боломжгүй"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматаар эргэх"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Дэлгэцийг автоматаар эргүүлэх"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Байршил"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> байрлалд нэмнэ үү"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Байрлал буруу байна."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> байрлал"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Хавтан нэмсэн"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Хавтанг хассан"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Шуурхай тохиргоо засварлагч."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Тодорхойгүй"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бүх хавтанг шинэчлэх үү?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Шуурхай тохиргооны бүх хавтан төхөөрөмжийн эх тохиргоо руу шинэчлэгдэнэ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 9fa40510eed0..2c5a9a85845d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> शी कनेक्‍ट केले."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> शी कनेक्ट केले."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"गटाचा विस्तार करा."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"डिव्हाइस गटामध्ये जोडा."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"डिव्हाइस गटामधून काढून टाका."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"अ‍ॅप उघडा."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"कनेक्ट केले नाही."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"रोमिंग"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"श्रवणयंत्रे"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सुरू करत आहे…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ब्राइटनेस टॉप ॲपद्वारे नियंत्रित केला जात असल्यामुळे ॲडजस्ट करू शकत नाही"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ऑटो-रोटेट स्क्रीन"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> स्थानावर जोडा"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"स्थान चुकीचे आहे."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थान <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोडली"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल काढून टाकली"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सर्व टाइल रीसेट करायच्या?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"सर्व क्विक सेटिंग्ज टाइल डिव्हाइसच्या मूळ सेटिंग्जवर रीसेट केल्या जातील"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 91e7e6340497..557509860f07 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan pada kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kedudukan tidak sah."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Jubin ditambah"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Jubin dialih keluar"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tetapkan semula semua jubin?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua jubin Tetapan Pantas akan ditetapkan semula kepada tetapan asal peranti"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 703562e0be12..b428422e5f07 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>သို့ ချိတ်ဆက်ထား"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> သို့ချိတ်ဆက်ထားပါသည်။"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"အုပ်စုကို ပိုပြသည်။"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"အဖွဲ့သို့ စက်ပစ္စည်းထည့်ရန်။"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"အဖွဲ့မှ စက်ပစ္စည်းကို ဖယ်ရှားရန်။"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"အပလီကေးရှင်းကို ဖွင့်သည်။"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"ချိတ်ဆက်မထားပါ"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ပြင်ပကွန်ရက်သုံးခြင်း"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"အဝင်"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"နားကြားကိရိယာ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ဖွင့်နေသည်…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"အပေါ်အက်ပ်မှ ထိန်းချုပ်ထားသောကြောင့် တောက်ပမှုကို ချိန်ညှိ၍ မရပါ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထားသို့ ပေါင်းထည့်ရန်"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"နေရာ မမှန်ပါ။"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထား"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"အကွက်ငယ်ကို ထည့်ပြီးပါပြီ"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"အကွက်ငယ်ကို ဖယ်ရှားပြီးပါပြီ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"အမျိုးအမည်မသိ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"အကွက်ငယ်အားလုံးကို ပြင်ဆင်သတ်မှတ်မလား။"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"အမြန်ဆက်တင်များ အကွက်ငယ်အားလုံးကို စက်ပစ္စည်း၏ မူရင်းဆက်တင်များသို့ ပြင်ဆင်သတ်မှတ်ပါမည်"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>၊ <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b75f644ec397..95740758c6e7 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Koblet til <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Koblet til <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Utvid gruppen."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Legg til enheten i gruppen."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Fjern enheten fra gruppen."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Åpne appen."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ikke tilkoblet."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Innenhet"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Slår på …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Kan ikke justere lysstyrken, fordi den kontrolleres av den øvre appen"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotér automatisk"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotér skjermen automatisk"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Sted"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Legg til posisjonen <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisjonen er ugyldig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisjon <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"En infobrikke er lagt til"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"En infobrikke er fjernet"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukjent"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du tilbakestille alle brikkene?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle brikker for hurtiginnstillinger tilbakestilles til enhetens opprinnelige innstillinger"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index cd20defc7849..4d37f8fd760b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> मा जडित।"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> मा कनेक्ट गरियो।"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"समूह एक्स्पान्ड गर्नुहोस्।"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"समूहमा डिभाइस हाल्नुहोस्।"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"समूहबाट डिभाइस हटाउनुहोस्।"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"एप खोल्नुहोस्।"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"जडान नगरिएको।"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"रोमिङ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"हियरिङ डिभाइसहरू"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सक्रिय गर्दै…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"सिरानको एपले चमक नियन्त्रण गरिरहेकाले चमक मिलाउन मिल्दैन"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"लोकेसन"</string>
@@ -997,8 +994,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकताका सूचना आइकनहरू देखाउनुहोस्"</string>
<string name="other" msgid="429768510980739978">"अन्य"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"टाइलको आकार टगल गर्नुहोस्"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"टाइल हटाउनुहोस्"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"अन्तिम स्थानमा टाइल हाल्नुहोस्"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"टाइल सार्नुहोस्"</string>
@@ -1007,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल यो अवस्था <xliff:g id="POSITION">%1$d</xliff:g> मा हाल्नुहोस्"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"पोजिसन अवैध छ।"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल हालियो"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाइयो"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string>
@@ -1551,10 +1549,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"आफूले हालसालै चलाएका एपहरू हेर्न तीन वटा औँलाले टचप्याडमा माथितिर स्वाइप गर्नुहोस् र होल्ड गर्नुहोस्"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"आफ्ना सबै एपहरू हेर्न आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"जानकारी लुकाउन सम्पादन गरिएको"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"हेर्न अनलक गर्नुहोस्"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"कोड हेर्न अनलक गर्नुहोस्"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"सान्दर्भिक शिक्षा"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"पछाडि जान आफ्नो टचप्याड प्रयोग गर्नुहोस्"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"तीन वटा औँला प्रयोग गरी बायाँ वा दायाँतिर स्वाइप गर्नुहोस्। थप जेस्चर प्रयोग गर्ने तरिका सिक्न ट्याप गर्नुहोस्।"</string>
@@ -1577,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सबै टाइलहरू रिसेट गर्ने हो?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"द्रुत सेटिङका सबै टाइलहरू रिसेट गरी डिभाइसका मूल सेटिङ लागू गरिने छन्"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 1df27df11b86..26d87522595b 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Verbonden met <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Verbonden met <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Groep uitvouwen."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Voeg het apparaat aan de groep toe."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Verwijder het apparaat uit de groep."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"App openen."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Niet verbonden."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hoortoestellen"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aanzetten…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Kan de helderheid niet aanpassen omdat deze wordt beheerd door de bovenste app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Scherm automatisch draaien"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Toevoegen aan positie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positie ongeldig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Positie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tegel toegevoegd"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tegel verwijderd"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index ddb9157c3755..a0e360cf6bcb 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ଅବସ୍ଥିତିରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ଅବସ୍ଥିତି ଅବୈଧ ଅଟେ।"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ଅବସ୍ଥିତି <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ଟାଇଲ୍ ଯୋଗ କରାଯାଇଛି"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ଟାଇଲ୍ କାଢ଼ି ଦିଆଯାଇଛି"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ଅଜଣା"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ସମସ୍ତ ଟାଇଲକୁ ରିସେଟ କରିବେ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ସମସ୍ତ କୁଇକ ସେଟିଂସ ଟାଇଲ ଡିଭାଇସର ମୂଳ ସେଟିଂସରେ ରିସେଟ ହୋଇଯିବ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 39c02d245a89..f2a6612bdb8a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ਸਥਾਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ਮੌਜੂਦਾ ਥਾਂ ਅਵੈਧ ਹੈ।"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ਸਥਾਨ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ਟਾਇਲ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ਟਾਇਲ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ਅਗਿਆਤ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ਕੀ ਸਾਰੀਆਂ ਟਾਇਲਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ਸਾਰੀਆਂ ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਟਾਇਲਾਂ ਡੀਵਾਈਸ ਦੀਆਂ ਮੂਲ ਸੈਟਿੰਗਾਂ \'ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਣਗੀਆਂ"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b93bf3074ab0..99e99e1a2e6a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Połączono z <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Połączono z urządzeniem <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Rozwiń grupę."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Dodaj urządzenie do grupy."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Usuń urządzenie z grupy."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otwórz aplikację."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nie połączono."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Wejście"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparaty słuchowe"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Włączam…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Nie można dostosować jasności, ponieważ reguluje ją aplikacja na pierwszym planie"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoobracanie"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoobracanie ekranu"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokalizacja"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodaj w pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nieprawidłowa pozycja."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozycja <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dodano kartę"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Usunięto kartę"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nieznane"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Zresetować wszystkie kafelki?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Wszystkie kafelki Szybkich ustawień zostaną zresetowane do oryginalnych ustawień urządzenia"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 7c9028ba068d..4663dba04bc2 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expandir grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Adicionar dispositivo ao grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remover dispositivo do grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abrir aplicativo."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Sem conexão."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Não é possível ajustar o brilho, porque ele está sendo controlado pelo app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index a8e0f05c971c..7a0e4f6e68b2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ligado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Ligado a <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expanda o grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Adicionar dispositivo ao grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remover dispositivo do grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abra a aplicação."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Sem ligação."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"A ativar..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Não é possível ajustar o brilho porque está a ser controlado pela app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicione à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cartão adicionado"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cartão removido"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de definições rápidas."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 7c9028ba068d..4663dba04bc2 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Expandir grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Adicionar dispositivo ao grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Remover dispositivo do grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Abrir aplicativo."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Sem conexão."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Não é possível ajustar o brilho, porque ele está sendo controlado pelo app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 23270ea2e9d8..e8b826b940f4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectat la <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"S-a stabilit conexiunea la <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Extinde grupul."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Adaugă dispozitivul în grup."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Elimină dispozitivul din grup."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Deschide aplicația."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Neconectat."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Intrare"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparate auditive"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Se activează..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Nu se poate ajusta luminozitatea deoarece este controlată de aplicația de sus"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotire automată"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotirea automată a ecranului"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Locație"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adaugă pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Poziție nevalidă."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cardul a fost adăugat"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cardul a fost eliminat"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Necunoscută"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetezi toate cardurile?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toate cardurile Setări rapide se vor reseta la setările inițiale ale dispozitivului"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index e4c1d45bf912..52458ebd176d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>: подключено."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Подключено к: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Развернуть группу."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Добавить устройство в группу."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Удалить устройство из группы."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Открыть приложение."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Не подключено"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Устройство ввода"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слуховые аппараты"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включение…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Невозможно изменить яркость, поскольку ею управляет приложение сверху"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоповорот"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоповорот экрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Геолокация"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Недопустимое расположение."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панель добавлена"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панель удалена"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Сбросить все параметры?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Для всех параметров быстрых настроек будут восстановлены значения по умолчанию."</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 437a35b51e0e..84a981f9db89 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> වෙත සම්බන්ධ කරන ලදි."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> වෙත සම්බන්ධ විය."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"සමූහය දිගහැරීම"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"සමූහයට උපාංගය එක් කරන්න."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"උපාංගය සමූහයෙන් ඉවත් කරන්න."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"යෙදුම විවෘත කරන්න."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"සම්බන්ධ වී නැත."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"රෝමිං"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ආදානය"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ශ්‍රවණාධාරක"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ක්‍රියාත්මක කරමින්…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ඉහළ යෙදුම මඟින් එය පාලනය වන නිසා දීප්තිය ගැළපුම් කළ නොහැක"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ස්වයංක්‍රීය කරකැවීම"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ස්වයංක්‍රීයව-භ්‍රමණය වන තිරය"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ස්ථානය"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ස්ථානයට එක් කරන්න"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ස්ථානය අවලංගුයි."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ටයිල් එක එක් කරන ලදි"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ටයිල් ඉවත් කරන ලදි"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"නොදනී"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"සියලු ටයිල් නැවත සකසන්න ද?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"සියලු ඉක්මන් සැකසීම් ටයිල් උපාංගයේ මුල් සැකසීම් වෙත නැවත සකසනු ඇත"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 859c976630d7..78a332a6c45c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Pripojené k zariadeniu <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Pripojené k zariadeniu <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Rozbaliť skupinu"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Pridať zariadenie do skupiny"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Odstrániť zariadenie zo skupiny"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otvoriť aplikáciu"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nepripojené."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Načúvadlá"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapína sa…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Jas sa nedá upraviť, pretože ho ovláda horná aplikácia"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčanie"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčanie obrazovky"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridať na <xliff:g id="POSITION">%1$d</xliff:g>. pozíciu"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozícia je neplatná."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozícia"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Karta bola pridaná"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Karta bola odstránená"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rýchlych nastavení"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznáme"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Chcete resetovať všetky karty?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všetky karty rýchlych nastavení sa resetujú na pôvodné nastavenia zariadenia"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2a1ed4690ac5..93649f5039d0 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezava vzpostavljena z: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Vzpostavljena povezava: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Razširitev skupine."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Dodajte napravo v skupino."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Odstranite napravo iz skupine."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Odpiranje aplikacije."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ni povezan."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Gostovanje"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vhodna naprava"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Vklapljanje …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Svetlosti ni mogoče prilagoditi, ker jo nadzoruje aplikacija na vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Samodejno sukanje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Samodejno sukanje zaslona"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj je neveljaven."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ploščica je bila dodana"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ploščica je bila odstranjena"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Urejevalnik hitrih nastavitev."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznano"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite ponastaviti vse ploščice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vse ploščice v hitrih nastavitvah bodo ponastavljene na prvotne nastavitve naprave."</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 916595fb55b2..5e69808d7f63 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Lidhur me <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Është lidhur me <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Zgjero grupin."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Shto pajisjen te grupi."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Hiq pajisjen nga grupi."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Hap aplikacionin."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nuk është i lidhur."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Hyrja"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparatet e dëgjimit"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Po aktivizohet…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Ndriçimi nuk mund të rregullohet pasi po kontrollohet nga aplikacioni lart"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rrotullim automatik"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rrotullimi automatik i ekranit"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vendndodhja"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Shto te pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicion i pavlefshëm."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pllakëza u shtua"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pllakëza u hoq"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nuk njihet"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Të rivendosen të gjitha pllakëzat?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Të gjitha pllakëzat e \"Cilësimeve të shpejta\" do të rivendosen te cilësimet origjinale të pajisjes"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 6bf3a697ab0d..1b645a8e2017 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиција је неважећа."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Желите да ресетујете све плочице?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Све плочице Брзих подешавања ће се ресетовати на првобитна подешавања уређаја"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index aa9f4a4bfcd4..a4129e0afb18 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ansluten till <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Ansluten till <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Utöka gruppen."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Lägg till enheten i gruppen."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Ta bort enheten från gruppen."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Öppna appen."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Inte ansluten."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingång"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverar …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Det går inte att ändra ljusstyrkan eftersom den styrs av den översta appen"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotera automatiskt"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotera skärmen automatiskt"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Plats"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lägg till på position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen är ogiltig."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kortet har lagts till"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kortet har tagits bort"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigerare för snabbinställningar."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Okänt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vill du återställa alla rutor?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alla Snabbinställningsrutor återställs till enhetens ursprungliga inställningar"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 72bfb8312cc4..cb82afff7f91 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Imeunganishwa kwenye <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Imeunganishwa kwenye <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Panua kikundi."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Weka kifaa kwenye kikundi."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Ondoa kifaa kwenye kikundi."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Fungua programu."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Haijaunganishwa."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Mitandao ya ng\'ambo"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vifaa vya kuingiza sauti"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Visaidizi vya kusikia"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inawasha..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Imeshindwa kurekebisha mwangaza kwa sababu inadhibitiwa na programu iliyo juu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Zungusha kiotomatiki"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Skrini ijizungushe kiotomatiki"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ongeza kwenye nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nafasi si sahihi."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kigae kimewekwa"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kigae kimeondolewa"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Visivyojulikana"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Ungependa kubadilisha vigae vyote?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vigae vyote vya Mipangilio ya Haraka vitabadilishwa kuwa katika mipangilio halisi ya kifaa"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 41bb37efa623..f4f0424ade98 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -30,11 +30,6 @@
not appear immediately after user swipes to the side -->
<dimen name="qs_tiles_page_horizontal_margin">20dp</dimen>
- <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
- <dimen name="qs_media_rec_icon_top_margin">16dp</dimen>
- <dimen name="qs_media_rec_album_size">112dp</dimen>
- <dimen name="qs_media_rec_album_side_margin">16dp</dimen>
-
<dimen name="controls_panel_corner_radius">40dp</dimen>
<dimen name="lockscreen_shade_max_over_scroll_amount">42dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 31ab5155eb35..77be6ea6a64b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>க்கு இணைக்கப்பட்டது."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"குழுவை விரிவாக்கும்."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"குழுவில் சாதனத்தைச் சேர்க்கும்."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"குழுவிலிருந்து சாதனத்தை அகற்றும்."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ஆப்ஸைத் திறக்கும்."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"இணைக்கப்படவில்லை."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ரோமிங்"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"உள்ளீடு"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"செவித்துணைக் கருவி"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ஆன் செய்கிறது…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ஒளிர்வை மேலுள்ள ஆப்ஸ் கட்டுப்படுத்துவதால் அதை மாற்ற முடியவில்லை"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"தானாகச் சுழற்று"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"திரையைத் தானாகச் சுழற்று"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"இருப்பிடம்"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"நிலை தவறானது."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"கட்டம் சேர்க்கப்பட்டது"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"கட்டம் அகற்றப்பட்டது"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"தெரியவில்லை"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"அனைத்துக் கட்டங்களையும் மீட்டமைக்கவா?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"விரைவு அமைப்புகளின் கட்டங்கள் அனைத்தும் சாதனத்தின் அசல் அமைப்புகளுக்கு மீட்டமைக்கப்படும்"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index d26bfaccc6cc..b4665190f33d 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"గ్రూప్‌ను విస్తరించండి."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"గ్రూప్‌కి పరికరాన్ని జోడించండి."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"గ్రూప్ నుండి పరికరాన్ని తీసివేయండి."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"యాప్‌ను తెరవండి."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"కనెక్ట్ చేయబడలేదు."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"రోమింగ్"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ఇన్‌పుట్"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"వినికిడి పరికరాలు"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ఆన్ చేస్తోంది…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"దీనిని టాప్ యాప్ కంట్రోల్ చేస్తోంది కనుక బ్రైట్‌నెస్‌ను సర్దుబాటు చేయడం సాధ్యం కాదు"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ఆటో-రొటేట్‌"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"స్క్రీన్ ఆటో-రొటేట్‌"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string>
@@ -1007,6 +1004,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> స్థానానికి జోడించండి"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ప్రస్తుత పొజిషన్ చెల్లదు."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"టైల్ జోడించబడింది"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"టైల్ తీసివేయబడింది"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"శీఘ్ర సెట్టింగ్‌ల ఎడిటర్."</string>
@@ -1577,6 +1576,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"తెలియదు"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"టైల్స్ అన్ని రీసెట్ చేయాలా?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"అన్ని క్విక్ సెట్టింగ్‌ల టైల్స్, పరికరం తాలూకు ఒరిజినల్ సెట్టింగ్‌లకు రీసెట్ చేయబడతాయి"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 9196f95de203..e816c04a5e65 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1003,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"เพิ่มไปยังตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ตำแหน่งไม่ถูกต้อง"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"เพิ่มชิ้นส่วนแล้ว"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"นำชิ้นส่วนออกแล้ว"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ตัวแก้ไขการตั้งค่าด่วน"</string>
@@ -1571,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ไม่ทราบ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"รีเซ็ตการ์ดทั้งหมดใช่ไหม"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"การ์ดการตั้งค่าด่วนทั้งหมดจะรีเซ็ตเป็นการตั้งค่าเดิมของอุปกรณ์"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a6b0d6aa55df..d996218c64db 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Nakakonekta sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Nakakonekta sa <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"I-expand ang grupo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Idagdag ang device sa grupo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Alisin ang device sa grupo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Buksan ang application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Hindi nakakonekta."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Mga hearing aid"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ino-on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Hindi ma-adjust ang liwanag dahil kinokontrol ito ng nangingibabaw na app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"I-auto rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Awtomatikong i-rotate ang screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasyon"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Idagdag sa posisyong <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Invalid ang posisyon."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Idinagdag ang tile"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Inalis ang tile"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor ng Mga mabilisang setting."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 13d6cd7ff9fc..9d789417b09f 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ile bağlı."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> bağlantısı kuruldu."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Grubu genişlet."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Cihazı gruba ekle."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Cihazı gruptan kaldır."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Uygulama aç."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Bağlanmadı."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Dolaşım"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"İşitme cihazları"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Açılıyor…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Parlaklık ayarlanamıyor, çünkü bu özellik en üstteki uygulama tarafından kontrol ediliyor"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Otomatik döndür"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranı otomatik döndür"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Konum"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Konum geçersiz."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Konum: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kutu eklendi"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kutu kaldırıldı"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Bilinmiyor"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tüm ayar kutuları sıfırlansın mı?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tüm Hızlı Ayarlar kutuları cihazın özgün ayarlarına sıfırlanır"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index f0f4e38d6040..97e5bb70313f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -247,15 +247,13 @@
<string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Натисніть, щоб змінити налаштування пристрою"</string>
<string name="accessibility_bluetooth_device_settings_gear_with_name" msgid="114373701123165491">"<xliff:g id="DEVICE_NAME">%s</xliff:g>. Змінити налаштування пристрою"</string>
<string name="accessibility_bluetooth_device_settings_see_all" msgid="5260390270128256620">"Переглянути всі пристрої"</string>
- <string name="accessibility_bluetooth_device_settings_pair_new_device" msgid="7988547106800504256">"Підключити новий пристрій"</string>
+ <string name="accessibility_bluetooth_device_settings_pair_new_device" msgid="7988547106800504256">"Зв’язати новий пристрій"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Підключено до <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Під’єднано до пристрою <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Розгорнути групу"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Додати пристрій у групу."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Вилучити пристрій із групи."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Відкрити додаток"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Не з’єднано."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роумінг"</string>
@@ -308,7 +306,7 @@
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Немає спарених пристроїв"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Натисніть, щоб під’єднати або від’єднати пристрій"</string>
- <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Підключити новий пристрій"</string>
+ <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Зв’язати новий пристрій"</string>
<string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Показати всі"</string>
<string name="turn_on_bluetooth" msgid="5681370462180289071">"Увімкнути Bluetooth"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Підключено"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Джерело сигналу"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухові апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Увімкнення…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не вдається змінити яскравість, оскільки нею керує основний додаток"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автообертання"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично обертати екран"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string>
@@ -418,7 +415,7 @@
<string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Під’єднано"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Від’єднано"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Слухові апарати"</string>
- <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Підключити новий пристрій"</string>
+ <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Зв’язати новий пристрій"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Натисніть, щоб підключити новий пристрій"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиція недійсна."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Опцію додано"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Опцію вилучено"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невідомо"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Скинути всі панелі?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Усі панелі швидких налаштувань буде скинуто до стандартних налаштувань пристрою"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ef10b87cbd0f..41ba6b235284 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> سے منسلک ہیں۔"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> سے منسلک ہے۔"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"گروپ کو پھیلائیں۔"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"آلہ کو گروپ شامل کریں۔"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"آلہ کو گروپ سے ہٹائیں"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ایپلیکیشن کھولیں۔"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"مربوط نہیں ہے۔"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"رومنگ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ان پٹ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعتی آلات"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"آن ہو رہا ہے…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"چمک کو ایڈجسٹ نہیں کیا جا سکتا کیونکہ اسے سرفہرست ایپ کے ذریعے کنٹرول کیا جا رہا ہے"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"خود کار طور پر گھمائیں"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"اسکرین کو خود کار طور پر گھمائیں"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"مقام"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g> میں شامل کریں"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"پوزیشن غلط ہے۔"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ٹائل کو شامل کیا گیا"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ٹائل کو ہٹا دیا گیا"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"فوری ترتیبات کا ایڈیٹر۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index facc51f2a1f6..f713ddc13b80 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ulangan: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Bunga ulangan: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Guruhni yoying."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Qurilmani guruhga kiritish."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Qurilmani guruhdan olib tashlash."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Ilovani oching."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Ulanmagan."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Rouming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Kirish"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eshitish moslamalari"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Yoqilmoqda…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Yorqinlikni sozlash imkonsiz, chunki tepadago ilova tomonidan boshqariladi"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bu joyga kiritish: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozitsiya yaroqsiz."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Joylashuv: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Katakcha kiritildi"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Katakcha olib tashlandi"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Noaniq"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Barcha katakchalar asliga qaytarilsinmi?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Barcha Tezkor sozlamalar katakchalari qurilmaning asl sozlamalariga qaytariladi"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 80db132b304f..2f266a781525 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Đã kết nối với <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Đã kết nối với <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Mở rộng nhóm."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Thêm thiết bị vào nhóm."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Xoá thiết bị khỏi nhóm."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Mở ứng dụng."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Chưa được kết nối."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Chuyển vùng"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Thiết bị đầu vào"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Thiết bị trợ thính"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Đang bật…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Không điều chỉnh được độ sáng do ứng dụng ở trên cùng đang điều khiển độ sáng"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Tự động xoay"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Tự động xoay màn hình"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vị trí"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Thêm vào vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Vị trí không hợp lệ."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Đã thêm thẻ thông tin"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Đã xóa thẻ thông tin"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Không xác định"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Đặt lại mọi ô?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Mọi ô Cài đặt nhanh sẽ được đặt lại về chế độ cài đặt ban đầu của thiết bị"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index feb3989114cb..480debcb239b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已连接到<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"已连接到 <xliff:g id="CAST">%s</xliff:g>。"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"展开群组。"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"将设备添加到群组。"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"从群组中移除设备。"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"打开应用。"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"未连接。"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"漫游"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"输入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助听器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在开启…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"亮度无法调整,因为它正在被顶层应用控制"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自动屏幕旋转"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自动旋转屏幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置信息"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置无效。"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加功能块"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除功能块"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"未知"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重置所有功能块吗?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有“快捷设置”功能块都将重置为设备的原始设置"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>,<xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 031df00e1c9c..bc9e0c580901 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"已連接至 <xliff:g id="CAST">%s</xliff:g>。"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"展開群組。"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"將裝置新增至群組。"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"從群組移除裝置。"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"開啟應用程式。"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"未連線。"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"漫遊"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在開啟…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"無法調整亮度,因為目前是由上層應用程式控制亮度"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"加去位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置冇效。"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"加咗圖塊"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"移除咗圖塊"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有圖塊嗎?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有「快速設定」圖塊將重設為裝置的原始設定"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>,<xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index df05577ff942..02fda5a68313 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"已連線至 <xliff:g id="CAST">%s</xliff:g>。"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"展開群組。"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"將裝置加入群組。"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"從群組中移除裝置。"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"開啟應用程式。"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"尚未連線。"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"漫遊"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"開啟中…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"無法調整亮度,因為目前是由上層應用程式控制亮度"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"定位"</string>
@@ -1006,6 +1003,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"新增到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置無效。"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已新增設定方塊"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除設定方塊"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string>
@@ -1574,6 +1573,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有設定方塊嗎?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有快速設定方塊都會恢復裝置的原始設定"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>、<xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d571f0e58c92..886cbdf2b097 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -254,10 +254,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Xhuma ku-<xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Ixhumeke ku-<xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Nweba iqembu."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Faka idivayisi eqenjini."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Susa idivayisi eqenjini."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Vula i-application."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Akuxhunyiwe"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Iyazulazula"</string>
@@ -335,8 +333,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Okokufaka"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Imishini yendlebe"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Iyavula..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Ayikwazi ukulungisa ukukhanya ngoba ilawulwa yi-app ephezulu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ukuphenduka okuzenzakalelayo"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Phendula iskrini ngokuzenzakalela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Indawo"</string>
@@ -1008,6 +1005,8 @@
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engeza kusikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Indawo ayivumelekile."</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Isikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
+ <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
+ <skip />
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ithayela lingeziwe"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ithayela likhishiwe"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string>
@@ -1576,6 +1575,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Akwaziwa"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Qala kabusha onke amathayela?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Ithayela Lamasethingi Asheshayo lizosetha kabusha libuyele kumasethingi okuqala edivayisi"</string>
- <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
- <skip />
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 4995858f95a4..78e719f6289a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -98,10 +98,6 @@
TODO (b/293252410) - change this comment/resource when flag is enabled -->
<integer name="small_land_lockscreen_quick_settings_max_rows">2</integer>
- <!-- If the dp width of the available space is <= this value, potentially adjust the number
- of media recommendation items-->
- <integer name="default_qs_media_rec_width_dp">380</integer>
-
<!-- The number of columns that the top level tiles span in the QuickSettings -->
<!-- The default tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7c370d3bc064..8342a9cc244b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1342,19 +1342,6 @@
<dimen name="qs_media_session_collapsed_legacy_guideline">144dp</dimen>
<dimen name="qs_media_session_collapsed_guideline">168dp</dimen>
- <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
- <dimen name="qs_media_rec_default_width">380dp</dimen>
- <dimen name="qs_media_rec_icon_top_margin">16dp</dimen>
- <dimen name="qs_media_rec_album_icon_size">16dp</dimen>
- <dimen name="qs_media_rec_album_size">88dp</dimen>
- <dimen name="qs_media_rec_album_width">110dp</dimen>
- <dimen name="qs_media_rec_album_height_expanded">108dp</dimen>
- <dimen name="qs_media_rec_album_height_collapsed">77dp</dimen>
- <dimen name="qs_media_rec_album_side_margin">16dp</dimen>
- <dimen name="qs_media_rec_album_bottom_margin">8dp</dimen>
- <dimen name="qs_media_rec_album_title_bottom_margin">22dp</dimen>
- <dimen name="qs_media_rec_album_subtitle_height">12dp</dimen>
-
<!-- Chipbar -->
<!-- (Used for media tap-to-transfer chip for sender device and active unlock) -->
<dimen name="chipbar_outer_padding">16dp</dimen>
@@ -2202,11 +2189,6 @@
<dimen name="volume_dialog_background_square_corner_radius">12dp</dimen>
<dimen name="volume_dialog_ringer_drawer_margin">@dimen/volume_dialog_buttons_margin</dimen>
- <!--
- (volume_dialog_slider_width - volume_dialog_button_size) / 2
- This centers ringer drawer against the volume slider
- -->
- <dimen name="volume_dialog_ringer_drawer_diff_end_margin">6dp</dimen>
<dimen name="volume_dialog_ringer_drawer_button_size">@dimen/volume_dialog_button_size</dimen>
<dimen name="volume_dialog_ringer_drawer_button_icon_radius">10dp</dimen>
<dimen name="volume_dialog_ringer_selected_button_background_radius">20dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 786ac69dc8fd..c06c17a0844f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1042,6 +1042,8 @@
<string name="hearing_devices_tools_label">Tools</string>
<!-- QuickSettings: Tool name for hearing devices dialog related tools [CHAR LIMIT=40] [BACKUP_MESSAGE_ID=8916875614623730005]-->
<string name="quick_settings_hearing_devices_live_caption_title">Live Caption</string>
+ <!-- QuickSettings: Label for button to go to hearing devices settings page [CHAR_LIMIT=20] -->
+ <string name="hearing_devices_settings_button">Settings</string>
<!-- QuickSettings: Notes tile. The label of a quick settings tile for launching the default notes taking app. [CHAR LIMIT=NONE] -->
<string name="quick_settings_notes_label">Note</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 4431ddadc8de..7895ff7b90f6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -895,57 +895,6 @@
<item name="android:textColor">@android:color/system_on_primary_dark</item>
</style>
- <style name="MediaPlayer.Recommendation"/>
-
- <style name="MediaPlayer.Recommendation.Header">
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_marginTop">@dimen/qs_media_padding</item>
- <item name="android:layout_marginStart">@dimen/qs_media_padding</item>
- <item name="android:fontFamily">=@*android:string/config_headlineFontFamilyMedium</item>
- <item name="android:singleLine">true</item>
- <item name="android:textSize">14sp</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.AlbumContainer">
- <item name="android:layout_width">@dimen/qs_media_rec_album_size</item>
- <item name="android:layout_height">@dimen/qs_media_rec_album_size</item>
- <item name="android:background">@drawable/qs_media_light_source</item>
- <item name="android:layout_marginTop">@dimen/qs_media_padding</item>
- <item name="android:layout_marginBottom">@dimen/qs_media_rec_album_bottom_margin</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.AlbumContainer.Updated">
- <item name="android:layout_width">@dimen/qs_media_rec_album_width</item>
- <item name="android:minWidth">@dimen/qs_media_rec_album_width</item>
- <item name="android:minHeight">@dimen/qs_media_rec_album_height_collapsed</item>
- <item name="android:background">@drawable/qs_media_light_source</item>
- <item name="android:layout_marginTop">@dimen/qs_media_info_spacing</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.Album">
- <item name="android:backgroundTint">@color/media_player_album_bg</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.Text">
- <item name="android:layout_width">@dimen/qs_media_rec_album_size</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:maxLines">1</item>
- <item name="android:ellipsize">end</item>
- <item name="android:textSize">14sp</item>
- <item name="android:gravity">start</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.Text.Title">
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- </style>
-
- <style name="MediaPlayer.Recommendation.Text.Subtitle">
- <item name="android:textColor">?android:attr/textColorSecondary</item>
- </style>
-
-
<!-- Used to style charging animation AVD animation -->
<style name="ChargingAnim" />
diff --git a/packages/SystemUI/res/xml/media_recommendations_collapsed.xml b/packages/SystemUI/res/xml/media_recommendations_collapsed.xml
deleted file mode 100644
index d3be3c7de5ad..000000000000
--- a/packages/SystemUI/res/xml/media_recommendations_collapsed.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<ConstraintSet
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- >
-
- <Constraint
- android:id="@+id/sizing_view"
- android:layout_width="match_parent"
- android:layout_height="@dimen/qs_media_session_height_collapsed"
- />
-
- <Constraint
- android:id="@+id/media_rec_title"
- style="@style/MediaPlayer.Recommendation.Header"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-
- <Constraint
- android:id="@+id/media_cover1_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_collapsed"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- android:layout_marginStart="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_cover2_container"/>
-
-
- <Constraint
- android:id="@+id/media_cover2_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_collapsed"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toEndOf="@id/media_cover1_container"
- app:layout_constraintEnd_toStartOf="@id/media_cover3_container"/>
-
- <Constraint
- android:id="@+id/media_cover3_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_collapsed"
- android:layout_marginEnd="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toEndOf="@id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-
-</ConstraintSet>
diff --git a/packages/SystemUI/res/xml/media_recommendations_expanded.xml b/packages/SystemUI/res/xml/media_recommendations_expanded.xml
deleted file mode 100644
index 88c70552e9e8..000000000000
--- a/packages/SystemUI/res/xml/media_recommendations_expanded.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<ConstraintSet
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- >
-
- <Constraint
- android:id="@+id/sizing_view"
- android:layout_width="match_parent"
- android:layout_height="@dimen/qs_media_session_height_expanded"
- />
-
- <Constraint
- android:id="@+id/media_rec_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginStart="@dimen/qs_media_padding"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:singleLine="true"
- android:textSize="14sp"
- android:textColor="@color/notification_primary_text_color"/>
-
- <Constraint
- android:id="@+id/media_cover1_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_expanded"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- android:layout_marginStart="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_cover2_container"/>
-
-
- <Constraint
- android:id="@+id/media_cover2_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_expanded"
- android:layout_marginEnd="@dimen/qs_media_info_spacing"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toEndOf="@id/media_cover1_container"
- app:layout_constraintEnd_toStartOf="@id/media_cover3_container"/>
-
- <Constraint
- android:id="@+id/media_cover3_container"
- style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated"
- android:layout_height="@dimen/qs_media_rec_album_height_expanded"
- android:layout_marginEnd="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_rec_title"
- app:layout_constraintStart_toEndOf="@id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-
-</ConstraintSet>
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index ae3a76e2d2ca..8d7cab41ea20 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -51,6 +51,7 @@ android_library {
":wm_shell-shared-aidls",
],
static_libs: [
+ "com.android.systemui.dagger-api",
"BiometricsSharedLib",
"PlatformAnimationLib",
"PluginCoreLib",
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
index a2b6e2cf9ae3..f276a82baaef 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
@@ -41,7 +41,7 @@ class CombinedCondition
constructor(
private val scope: CoroutineScope,
private val conditions: Collection<Condition>,
- @Evaluator.ConditionOperand private val operand: Int
+ @Evaluator.ConditionOperand private val operand: Int,
) : Condition(scope, null, false) {
private var job: Job? = null
@@ -54,7 +54,7 @@ constructor(
lazilyEvaluate(
conditions = groupedConditions.getOrDefault(true, emptyList()),
- filterUnknown = true
+ filterUnknown = true,
)
.distinctUntilChanged()
.flatMapLatest { overriddenValue ->
@@ -62,7 +62,7 @@ constructor(
if (overriddenValue == null) {
lazilyEvaluate(
conditions = groupedConditions.getOrDefault(false, emptyList()),
- filterUnknown = false
+ filterUnknown = false,
)
} else {
flowOf(overriddenValue)
@@ -188,7 +188,6 @@ constructor(
return startStrategy
}
- override fun getStartStrategy(): Int {
- return _startStrategy
- }
+ override val startStrategy: Int
+ get() = _startStrategy
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java
deleted file mode 100644
index 670feeba6e8a..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.condition;
-
-import android.util.Log;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleEventObserver;
-import androidx.lifecycle.LifecycleOwner;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Base class for a condition that needs to be fulfilled in order for {@link Monitor} to inform
- * its callbacks.
- */
-public abstract class Condition {
- private final String mTag = getClass().getSimpleName();
-
- private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
- private final boolean mOverriding;
- private final CoroutineScope mScope;
- private Boolean mIsConditionMet;
- private boolean mStarted = false;
-
- /**
- * By default, conditions have an initial value of false and are not overriding.
- */
- public Condition(CoroutineScope scope) {
- this(scope, false, false);
- }
-
- /**
- * Constructor for specifying initial state and overriding condition attribute.
- *
- * @param initialConditionMet Initial state of the condition.
- * @param overriding Whether this condition overrides others.
- */
- protected Condition(CoroutineScope scope, Boolean initialConditionMet, boolean overriding) {
- mIsConditionMet = initialConditionMet;
- mOverriding = overriding;
- mScope = scope;
- }
-
- /**
- * Starts monitoring the condition.
- */
- protected abstract void start();
-
- /**
- * Stops monitoring the condition.
- */
- protected abstract void stop();
-
- /**
- * Condition should be started as soon as there is an active subscription.
- */
- public static final int START_EAGERLY = 0;
- /**
- * Condition should be started lazily only if needed. But once started, it will not be cancelled
- * unless there are no more active subscriptions.
- */
- public static final int START_LAZILY = 1;
- /**
- * Condition should be started lazily only if needed, and can be stopped when not needed. This
- * should be used for conditions which are expensive to keep running.
- */
- public static final int START_WHEN_NEEDED = 2;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({START_EAGERLY, START_LAZILY, START_WHEN_NEEDED})
- @interface StartStrategy {
- }
-
- @StartStrategy
- protected abstract int getStartStrategy();
-
- /**
- * Returns whether the current condition overrides
- */
- public boolean isOverridingCondition() {
- return mOverriding;
- }
-
- /**
- * Registers a callback to receive updates once started. This should be called before
- * {@link #start()}. Also triggers the callback immediately if already started.
- */
- public void addCallback(@NonNull Callback callback) {
- if (shouldLog()) Log.d(mTag, "adding callback");
- mCallbacks.add(new WeakReference<>(callback));
-
- if (mStarted) {
- callback.onConditionChanged(this);
- return;
- }
-
- start();
- mStarted = true;
- }
-
- /**
- * Removes the provided callback from further receiving updates.
- */
- public void removeCallback(@NonNull Callback callback) {
- if (shouldLog()) Log.d(mTag, "removing callback");
- final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
- while (iterator.hasNext()) {
- final Callback cb = iterator.next().get();
- if (cb == null || cb == callback) {
- iterator.remove();
- }
- }
-
- if (!mCallbacks.isEmpty() || !mStarted) {
- return;
- }
-
- stop();
- mStarted = false;
- }
-
- /**
- * Wrapper to {@link #addCallback(Callback)} when a lifecycle is in the resumed state
- * and {@link #removeCallback(Callback)} when not resumed automatically.
- */
- public Callback observe(LifecycleOwner owner, Callback listener) {
- return observe(owner.getLifecycle(), listener);
- }
-
- /**
- * Wrapper to {@link #addCallback(Callback)} when a lifecycle is in the resumed state
- * and {@link #removeCallback(Condition.Callback)} when not resumed automatically.
- */
- public Callback observe(Lifecycle lifecycle, Callback listener) {
- lifecycle.addObserver((LifecycleEventObserver) (lifecycleOwner, event) -> {
- if (event == Lifecycle.Event.ON_RESUME) {
- addCallback(listener);
- } else if (event == Lifecycle.Event.ON_PAUSE) {
- removeCallback(listener);
- }
- });
- return listener;
- }
-
- /**
- * Updates the value for whether the condition has been fulfilled, and sends an update if the
- * value changes and any callback is registered.
- *
- * @param isConditionMet True if the condition has been fulfilled. False otherwise.
- */
- protected void updateCondition(boolean isConditionMet) {
- if (mIsConditionMet != null && mIsConditionMet == isConditionMet) {
- return;
- }
-
- if (shouldLog()) Log.d(mTag, "updating condition to " + isConditionMet);
- mIsConditionMet = isConditionMet;
- sendUpdate();
- }
-
- /**
- * Clears the set condition value. This is purposefully separate from
- * {@link #updateCondition(boolean)} to avoid confusion around {@code null} values.
- */
- protected void clearCondition() {
- if (mIsConditionMet == null) {
- return;
- }
-
- if (shouldLog()) Log.d(mTag, "clearing condition");
-
- mIsConditionMet = null;
- sendUpdate();
- }
-
- private void sendUpdate() {
- final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
- while (iterator.hasNext()) {
- final Callback cb = iterator.next().get();
- if (cb == null) {
- iterator.remove();
- } else {
- cb.onConditionChanged(this);
- }
- }
- }
-
- /**
- * Returns whether the condition is set. This method should be consulted to understand the
- * value of {@link #isConditionMet()}.
- *
- * @return {@code true} if value is present, {@code false} otherwise.
- */
- public boolean isConditionSet() {
- return mIsConditionMet != null;
- }
-
- /**
- * Returns whether the condition has been met. Note that this method will return {@code false}
- * if the condition is not set as well.
- */
- public boolean isConditionMet() {
- return Boolean.TRUE.equals(mIsConditionMet);
- }
-
- protected final boolean shouldLog() {
- return Log.isLoggable(mTag, Log.DEBUG);
- }
-
- protected final String getTag() {
- if (isOverridingCondition()) {
- return mTag + "[OVRD]";
- }
-
- return mTag;
- }
-
- /**
- * Returns the state of the condition.
- * - "Invalid", condition hasn't been set / not monitored
- * - "True", condition has been met
- * - "False", condition has not been met
- */
- protected final String getState() {
- if (!isConditionSet()) {
- return "Invalid";
- }
- return isConditionMet() ? "True" : "False";
- }
-
- /**
- * Creates a new condition which will only be true when both this condition and all the provided
- * conditions are true.
- */
- public Condition and(@NonNull Collection<Condition> others) {
- final List<Condition> conditions = new ArrayList<>();
- conditions.add(this);
- conditions.addAll(others);
- return new CombinedCondition(mScope, conditions, Evaluator.OP_AND);
- }
-
- /**
- * Creates a new condition which will only be true when both this condition and the provided
- * condition is true.
- */
- public Condition and(@NonNull Condition... others) {
- return and(Arrays.asList(others));
- }
-
- /**
- * Creates a new condition which will only be true when either this condition or any of the
- * provided conditions are true.
- */
- public Condition or(@NonNull Collection<Condition> others) {
- final List<Condition> conditions = new ArrayList<>();
- conditions.add(this);
- conditions.addAll(others);
- return new CombinedCondition(mScope, conditions, Evaluator.OP_OR);
- }
-
- /**
- * Creates a new condition which will only be true when either this condition or the provided
- * condition is true.
- */
- public Condition or(@NonNull Condition... others) {
- return or(Arrays.asList(others));
- }
-
- /**
- * Callback that receives updates about whether the condition has been fulfilled.
- */
- public interface Callback {
- /**
- * Called when the fulfillment of the condition changes.
- *
- * @param condition The condition in question.
- */
- void onConditionChanged(Condition condition);
- }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt
new file mode 100644
index 000000000000..69236b48ed51
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.shared.condition
+
+import android.util.Log
+import androidx.annotation.IntDef
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
+import androidx.lifecycle.LifecycleOwner
+import java.lang.ref.WeakReference
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * Base class for a condition that needs to be fulfilled in order for [Monitor] to inform its
+ * callbacks.
+ */
+abstract class Condition
+/**
+ * Constructor for specifying initial state and overriding condition attribute.
+ *
+ * @param initialConditionMet Initial state of the condition.
+ * @param overriding Whether this condition overrides others.
+ */
+@JvmOverloads
+protected constructor(
+ private val _scope: CoroutineScope,
+ private var _isConditionMet: Boolean? = false,
+ /** Returns whether the current condition overrides */
+ val isOverridingCondition: Boolean = false,
+) {
+ private val mTag: String = javaClass.simpleName
+
+ private val _callbacks = mutableListOf<WeakReference<Callback>>()
+ private var _started = false
+
+ /** Starts monitoring the condition. */
+ protected abstract fun start()
+
+ /** Stops monitoring the condition. */
+ protected abstract fun stop()
+
+ @Retention(AnnotationRetention.SOURCE)
+ @IntDef(START_EAGERLY, START_LAZILY, START_WHEN_NEEDED)
+ annotation class StartStrategy
+
+ @get:StartStrategy abstract val startStrategy: Int
+
+ /**
+ * Registers a callback to receive updates once started. This should be called before [.start].
+ * Also triggers the callback immediately if already started.
+ */
+ fun addCallback(callback: Callback) {
+ if (shouldLog()) Log.d(mTag, "adding callback")
+ _callbacks.add(WeakReference(callback))
+
+ if (_started) {
+ callback.onConditionChanged(this)
+ return
+ }
+
+ start()
+ _started = true
+ }
+
+ /** Removes the provided callback from further receiving updates. */
+ fun removeCallback(callback: Callback) {
+ if (shouldLog()) Log.d(mTag, "removing callback")
+ val iterator = _callbacks.iterator()
+ while (iterator.hasNext()) {
+ val cb = iterator.next().get()
+ if (cb == null || cb === callback) {
+ iterator.remove()
+ }
+ }
+
+ if (_callbacks.isNotEmpty() || !_started) {
+ return
+ }
+
+ stop()
+ _started = false
+ }
+
+ /**
+ * Wrapper to [.addCallback] when a lifecycle is in the resumed state and [.removeCallback] when
+ * not resumed automatically.
+ */
+ fun observe(owner: LifecycleOwner, listener: Callback): Callback {
+ return observe(owner.lifecycle, listener)
+ }
+
+ /**
+ * Wrapper to [.addCallback] when a lifecycle is in the resumed state and [.removeCallback] when
+ * not resumed automatically.
+ */
+ fun observe(lifecycle: Lifecycle, listener: Callback): Callback {
+ lifecycle.addObserver(
+ LifecycleEventObserver { lifecycleOwner: LifecycleOwner?, event: Lifecycle.Event ->
+ if (event == Lifecycle.Event.ON_RESUME) {
+ addCallback(listener)
+ } else if (event == Lifecycle.Event.ON_PAUSE) {
+ removeCallback(listener)
+ }
+ }
+ )
+ return listener
+ }
+
+ /**
+ * Updates the value for whether the condition has been fulfilled, and sends an update if the
+ * value changes and any callback is registered.
+ *
+ * @param isConditionMet True if the condition has been fulfilled. False otherwise.
+ */
+ protected fun updateCondition(isConditionMet: Boolean) {
+ if (_isConditionMet != null && _isConditionMet == isConditionMet) {
+ return
+ }
+
+ if (shouldLog()) Log.d(mTag, "updating condition to $isConditionMet")
+ _isConditionMet = isConditionMet
+ sendUpdate()
+ }
+
+ /**
+ * Clears the set condition value. This is purposefully separate from [.updateCondition] to
+ * avoid confusion around `null` values.
+ */
+ fun clearCondition() {
+ if (_isConditionMet == null) {
+ return
+ }
+
+ if (shouldLog()) Log.d(mTag, "clearing condition")
+
+ _isConditionMet = null
+ sendUpdate()
+ }
+
+ private fun sendUpdate() {
+ val iterator = _callbacks.iterator()
+ while (iterator.hasNext()) {
+ val cb = iterator.next().get()
+ if (cb == null) {
+ iterator.remove()
+ } else {
+ cb.onConditionChanged(this)
+ }
+ }
+ }
+
+ val isConditionSet: Boolean
+ /**
+ * Returns whether the condition is set. This method should be consulted to understand the
+ * value of [.isConditionMet].
+ *
+ * @return `true` if value is present, `false` otherwise.
+ */
+ get() = _isConditionMet != null
+
+ val isConditionMet: Boolean
+ /**
+ * Returns whether the condition has been met. Note that this method will return `false` if
+ * the condition is not set as well.
+ */
+ get() = true == _isConditionMet
+
+ protected fun shouldLog(): Boolean {
+ return Log.isLoggable(mTag, Log.DEBUG)
+ }
+
+ val tag: String
+ get() {
+ if (isOverridingCondition) {
+ return "$mTag[OVRD]"
+ }
+
+ return mTag
+ }
+
+ val state: String
+ /**
+ * Returns the state of the condition.
+ * - "Invalid", condition hasn't been set / not monitored
+ * - "True", condition has been met
+ * - "False", condition has not been met
+ */
+ get() {
+ if (!isConditionSet) {
+ return "Invalid"
+ }
+ return if (isConditionMet) "True" else "False"
+ }
+
+ /**
+ * Creates a new condition which will only be true when both this condition and all the provided
+ * conditions are true.
+ */
+ fun and(others: Collection<Condition>): Condition {
+ val conditions: List<Condition> = listOf(this, *others.toTypedArray())
+ return CombinedCondition(_scope, conditions, Evaluator.OP_AND)
+ }
+
+ /**
+ * Creates a new condition which will only be true when both this condition and the provided
+ * condition is true.
+ */
+ fun and(vararg others: Condition): Condition {
+ return and(listOf(*others))
+ }
+
+ /**
+ * Creates a new condition which will only be true when either this condition or any of the
+ * provided conditions are true.
+ */
+ fun or(others: Collection<Condition>): Condition {
+ val conditions: MutableList<Condition> = ArrayList()
+ conditions.add(this)
+ conditions.addAll(others)
+ return CombinedCondition(_scope, conditions, Evaluator.OP_OR)
+ }
+
+ /**
+ * Creates a new condition which will only be true when either this condition or the provided
+ * condition is true.
+ */
+ fun or(vararg others: Condition): Condition {
+ return or(listOf(*others))
+ }
+
+ /** Callback that receives updates about whether the condition has been fulfilled. */
+ fun interface Callback {
+ /**
+ * Called when the fulfillment of the condition changes.
+ *
+ * @param condition The condition in question.
+ */
+ fun onConditionChanged(condition: Condition)
+ }
+
+ companion object {
+ /** Condition should be started as soon as there is an active subscription. */
+ const val START_EAGERLY: Int = 0
+
+ /**
+ * Condition should be started lazily only if needed. But once started, it will not be
+ * cancelled unless there are no more active subscriptions.
+ */
+ const val START_LAZILY: Int = 1
+
+ /**
+ * Condition should be started lazily only if needed, and can be stopped when not needed.
+ * This should be used for conditions which are expensive to keep running.
+ */
+ const val START_WHEN_NEEDED: Int = 2
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
index 84edc3577007..0f535cdfa5cc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
@@ -14,7 +14,7 @@ import kotlinx.coroutines.launch
fun Flow<Boolean>.toCondition(
scope: CoroutineScope,
@StartStrategy strategy: Int,
- initialValue: Boolean? = null
+ initialValue: Boolean? = null,
): Condition {
return object : Condition(scope, initialValue, false) {
var job: Job? = null
@@ -28,7 +28,8 @@ fun Flow<Boolean>.toCondition(
job = null
}
- override fun getStartStrategy() = strategy
+ override val startStrategy: Int
+ get() = strategy
}
}
@@ -36,13 +37,16 @@ fun Flow<Boolean>.toCondition(
fun Condition.toFlow(): Flow<Boolean?> {
return callbackFlow {
val callback =
- Condition.Callback { condition ->
- if (condition.isConditionSet) {
- trySend(condition.isConditionMet)
- } else {
- trySend(null)
+ object : Condition.Callback {
+ override fun onConditionChanged(condition: Condition) {
+ if (condition.isConditionSet) {
+ trySend(condition.isConditionMet)
+ } else {
+ trySend(null)
+ }
}
}
+
addCallback(callback)
callback.onConditionChanged(this@toFlow)
awaitClose { removeCallback(callback) }
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index dcbacec5b630..c880f057f44a 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -203,7 +203,9 @@ public class CarrierTextManager {
CarrierTextManagerLogger logger) {
mContext = context;
- mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
+ boolean hasTelephony = mContext.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ mIsEmergencyCallCapable = telephonyManager.isVoiceCapable() && hasTelephony;
mShowAirplaneMode = showAirplaneMode;
mShowMissingSim = showMissingSim;
@@ -221,9 +223,7 @@ public class CarrierTextManager {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLogger = logger;
mBgExecutor.execute(() -> {
- boolean supported = mContext.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
- if (supported && mNetworkSupported.compareAndSet(false, supported)) {
+ if (hasTelephony && mNetworkSupported.compareAndSet(false, hasTelephony)) {
// This will set/remove the listeners appropriately. Note that it will never double
// add the listeners.
handleSetListening(mCarrierTextCallback);
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index e827b2d54a19..1549b699eee6 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -56,6 +56,7 @@ import com.android.systemui.log.core.Logger
import com.android.systemui.modes.shared.ModesUi
import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockEventListener
import com.android.systemui.plugins.clocks.ClockFaceController
import com.android.systemui.plugins.clocks.ClockMessageBuffers
import com.android.systemui.plugins.clocks.ClockTickRate
@@ -148,7 +149,7 @@ constructor(
val clockStr = clock.toString()
loggers.forEach { it.d({ "New Clock: $str1" }) { str1 = clockStr } }
- clock.initialize(isDarkTheme(), dozeAmount.value, 0f, { onClockBoundsChanged.value = it })
+ clock.initialize(isDarkTheme(), dozeAmount.value, 0f, clockListener)
if (!regionSamplingEnabled) {
updateColors()
@@ -312,6 +313,13 @@ constructor(
private var zenData: ZenData? = null
private var alarmData: AlarmData? = null
+ private val clockListener =
+ object : ClockEventListener {
+ override fun onBoundsChanged(bounds: RectF) {
+ onClockBoundsChanged.value = bounds
+ }
+ }
+
private val configListener =
object : ConfigurationController.ConfigurationListener {
override fun onThemeChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/KairosActivatable.kt b/packages/SystemUI/src/com/android/systemui/KairosActivatable.kt
index 5e29ba91ce42..442d4abb23f7 100644
--- a/packages/SystemUI/src/com/android/systemui/KairosActivatable.kt
+++ b/packages/SystemUI/src/com/android/systemui/KairosActivatable.kt
@@ -19,23 +19,28 @@ package com.android.systemui
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.BuildSpec
import com.android.systemui.kairos.Events
import com.android.systemui.kairos.EventsLoop
import com.android.systemui.kairos.ExperimentalKairosApi
import com.android.systemui.kairos.Incremental
import com.android.systemui.kairos.IncrementalLoop
import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.RootKairosNetwork
import com.android.systemui.kairos.State
import com.android.systemui.kairos.StateLoop
+import com.android.systemui.kairos.TransactionScope
+import com.android.systemui.kairos.activateSpec
+import com.android.systemui.kairos.effect
import com.android.systemui.kairos.launchKairosNetwork
import com.android.systemui.kairos.launchScope
import dagger.Binds
import dagger.Module
-import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.Multibinds
import javax.inject.Inject
+import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -176,21 +181,40 @@ private class KairosBuilderImpl @Inject constructor() : KairosBuilder {
@SysUISingleton
@ExperimentalKairosApi
class KairosCoreStartable
-@Inject
-constructor(
- @Application private val appScope: CoroutineScope,
- private val kairosNetwork: KairosNetwork,
+private constructor(
+ private val appScope: CoroutineScope,
private val activatables: dagger.Lazy<Set<@JvmSuppressWildcards KairosActivatable>>,
-) : CoreStartable {
+ private val unwrappedNetwork: RootKairosNetwork,
+) : CoreStartable, KairosNetwork by unwrappedNetwork {
+
+ @Inject
+ constructor(
+ @Application appScope: CoroutineScope,
+ activatables: dagger.Lazy<Set<@JvmSuppressWildcards KairosActivatable>>,
+ ) : this(appScope, activatables, appScope.launchKairosNetwork())
+
+ private val started = CompletableDeferred<Unit>()
+
override fun start() {
appScope.launch {
- kairosNetwork.activateSpec {
+ unwrappedNetwork.activateSpec {
for (activatable in activatables.get()) {
launchScope { activatable.run { activate() } }
}
+ effect { started.complete(Unit) }
}
}
}
+
+ override suspend fun activateSpec(spec: BuildSpec<*>) {
+ started.await()
+ unwrappedNetwork.activateSpec(spec)
+ }
+
+ override suspend fun <R> transact(block: TransactionScope.() -> R): R {
+ started.await()
+ return unwrappedNetwork.transact(block)
+ }
}
@Module
@@ -203,10 +227,5 @@ interface KairosCoreStartableModule {
@Multibinds fun kairosActivatables(): Set<@JvmSuppressWildcards KairosActivatable>
- companion object {
- @Provides
- @SysUISingleton
- fun provideKairosNetwork(@Application scope: CoroutineScope): KairosNetwork =
- scope.launchKairosNetwork()
- }
+ @Binds fun bindKairosNetwork(impl: KairosCoreStartable): KairosNetwork
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesChecker.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesChecker.java
index 2d1cd03aea4d..20290f7b5373 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesChecker.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesChecker.java
@@ -99,10 +99,7 @@ public class HearingDevicesChecker {
private boolean isExclusivelyManagedBluetoothDevice(
@NonNull CachedBluetoothDevice cachedDevice) {
- if (com.android.settingslib.flags.Flags.enableHideExclusivelyManagedBluetoothDevice()) {
- return BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
- cachedDevice.getDevice());
- }
- return false;
+ return BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
+ cachedDevice.getDevice());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index b730c931be8b..08559f2eca8d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -19,6 +19,8 @@ package com.android.systemui.accessibility.hearingaid;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
+import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
+
import static java.util.Collections.emptyList;
import android.bluetooth.BluetoothHapClient;
@@ -263,6 +265,20 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
dialog.setTitle(R.string.quick_settings_hearing_devices_dialog_title);
dialog.setView(LayoutInflater.from(dialog.getContext()).inflate(
R.layout.hearing_devices_tile_dialog, null));
+ dialog.setNegativeButton(
+ R.string.hearing_devices_settings_button,
+ (dialogInterface, which) -> {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_SETTINGS_CLICK,
+ mLaunchSourceId);
+ final Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_DETAILS_SETTINGS)
+ .putExtra(Intent.EXTRA_COMPONENT_NAME,
+ ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+ mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
+ mDialogTransitionAnimator.createActivityTransitionController(
+ dialog));
+ },
+ /* dismissOnClick = */ true
+ );
dialog.setPositiveButton(
R.string.quick_settings_done,
/* onClick = */ null,
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
index fe1d5040c6f5..4a695d638713 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
@@ -39,7 +39,9 @@ enum class HearingDevicesUiEvent(private val id: Int) : UiEventLogger.UiEventEnu
@UiEvent(doc = "Expand the ambient volume controls")
HEARING_DEVICES_AMBIENT_EXPAND_CONTROLS(2153),
@UiEvent(doc = "Collapse the ambient volume controls")
- HEARING_DEVICES_AMBIENT_COLLAPSE_CONTROLS(2154);
+ HEARING_DEVICES_AMBIENT_COLLAPSE_CONTROLS(2154),
+ @UiEvent(doc = "Click on the device settings to enter hearing devices page")
+ HEARING_DEVICES_SETTINGS_CLICK(2172);
override fun getId(): Int = this.id
}
diff --git a/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt
index 0b578c65e915..113df2026e81 100644
--- a/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt
@@ -122,6 +122,10 @@ constructor(
return false
}
+ fun isBackCallbackRegistered(): Boolean {
+ return isCallbackRegistered
+ }
+
private fun registerBackCallback() {
if (isCallbackRegistered) {
return
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
index bfbc27d3a086..858cc00b86b9 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
@@ -21,7 +21,6 @@ import android.content.Context
import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.flags.Flags
import com.android.systemui.res.R
private val backgroundOn = R.drawable.settingslib_switch_bar_bg_on
@@ -222,12 +221,8 @@ internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
- return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
- !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
- BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
- } else {
+ return !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
- }
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -250,13 +245,9 @@ internal open class SavedDeviceItemFactory : DeviceItemFactory() {
isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
- return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
- !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
- cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
- !cachedDevice.isConnected
- } else {
- cachedDevice.bondState == BluetoothDevice.BOND_BONDED && !cachedDevice.isConnected
- }
+ return !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
+ cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
+ !cachedDevice.isConnected
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -279,18 +270,12 @@ internal class SavedHearingDeviceItemFactory : SavedDeviceItemFactory() {
isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
- return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
- !BluetoothUtils.isExclusivelyManagedBluetoothDevice(
- context,
- cachedDevice.getDevice(),
- ) &&
- cachedDevice.isHearingAidDevice &&
- cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
- !cachedDevice.isConnected
- } else {
+ return !BluetoothUtils.isExclusivelyManagedBluetoothDevice(
+ context,
+ cachedDevice.getDevice(),
+ ) &&
cachedDevice.isHearingAidDevice &&
- cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
- !cachedDevice.isConnected
- }
+ cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
+ !cachedDevice.isConnected
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt
new file mode 100644
index 000000000000..df6c1b18e3e9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.clipboardoverlay
+
+import android.content.ClipData
+import android.content.ClipDescription
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.text.TextUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+@SysUISingleton
+class ActionIntentCreator @Inject constructor() : IntentCreator {
+ override fun getTextEditorIntent(context: Context?) =
+ Intent(context, EditTextActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ }
+
+ override fun getShareIntent(clipData: ClipData, context: Context?): Intent {
+ val shareIntent = Intent(Intent.ACTION_SEND)
+
+ // From the ACTION_SEND docs:
+ // "If using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it should be the
+ // MIME type of the data in EXTRA_STREAM"
+ val uri = clipData.getItemAt(0).uri
+ shareIntent.apply {
+ if (uri != null) {
+ // We don't use setData here because some apps interpret this as "to:".
+ setType(clipData.description.getMimeType(0))
+ // Include URI in ClipData also, so that grantPermission picks it up.
+ setClipData(
+ ClipData(
+ ClipDescription("content", arrayOf(clipData.description.getMimeType(0))),
+ ClipData.Item(uri),
+ )
+ )
+ putExtra(Intent.EXTRA_STREAM, uri)
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ } else {
+ putExtra(Intent.EXTRA_TEXT, clipData.getItemAt(0).coerceToText(context).toString())
+ setType("text/plain")
+ }
+ }
+
+ return Intent.createChooser(shareIntent, null)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+
+ override fun getImageEditIntent(uri: Uri?, context: Context): Intent {
+ val editorPackage = context.getString(R.string.config_screenshotEditor)
+ return Intent(Intent.ACTION_EDIT).apply {
+ if (!TextUtils.isEmpty(editorPackage)) {
+ setComponent(ComponentName.unflattenFromString(editorPackage))
+ }
+ setDataAndType(uri, "image/*")
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ putExtra(EXTRA_EDIT_SOURCE, EDIT_SOURCE_CLIPBOARD)
+ }
+ }
+
+ override fun getRemoteCopyIntent(clipData: ClipData?, context: Context): Intent {
+ val remoteCopyPackage = context.getString(R.string.config_remoteCopyPackage)
+ return Intent(REMOTE_COPY_ACTION).apply {
+ if (!TextUtils.isEmpty(remoteCopyPackage)) {
+ setComponent(ComponentName.unflattenFromString(remoteCopyPackage))
+ }
+
+ setClipData(clipData)
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ }
+ }
+
+ companion object {
+ private const val EXTRA_EDIT_SOURCE: String = "edit_source"
+ private const val EDIT_SOURCE_CLIPBOARD: String = "clipboard"
+ private const val REMOTE_COPY_ACTION: String = "android.intent.action.REMOTE_COPY"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index ac747845267c..314b6e7f5a28 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -65,7 +65,6 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.OverlayWindowContext;
import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.res.R;
import com.android.systemui.screenshot.TimeoutHandler;
@@ -94,13 +93,13 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
private final ClipboardOverlayWindow mWindow;
private final TimeoutHandler mTimeoutHandler;
private final ClipboardOverlayUtils mClipboardUtils;
- private final FeatureFlags mFeatureFlags;
private final Executor mBgExecutor;
private final ClipboardImageLoader mClipboardImageLoader;
private final ClipboardTransitionExecutor mTransitionExecutor;
private final ClipboardOverlayView mView;
private final ClipboardIndicationProvider mClipboardIndicationProvider;
+ private final IntentCreator mIntentCreator;
private Runnable mOnSessionCompleteListener;
private Runnable mOnRemoteCopyTapped;
@@ -189,13 +188,13 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
BroadcastDispatcher broadcastDispatcher,
BroadcastSender broadcastSender,
TimeoutHandler timeoutHandler,
- FeatureFlags featureFlags,
ClipboardOverlayUtils clipboardUtils,
@Background Executor bgExecutor,
ClipboardImageLoader clipboardImageLoader,
ClipboardTransitionExecutor transitionExecutor,
ClipboardIndicationProvider clipboardIndicationProvider,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ IntentCreator intentCreator) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
mClipboardImageLoader = clipboardImageLoader;
@@ -203,6 +202,7 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
mClipboardIndicationProvider = clipboardIndicationProvider;
mClipboardLogger = new ClipboardLogger(uiEventLogger);
+ mIntentCreator = intentCreator;
mView = clipboardOverlayView;
mWindow = clipboardOverlayWindow;
@@ -211,7 +211,6 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
hideImmediate();
});
- mFeatureFlags = featureFlags;
mTimeoutHandler = timeoutHandler;
mTimeoutHandler.setDefaultTimeoutMillis(CLIPBOARD_DEFAULT_TIMEOUT_MILLIS);
@@ -508,7 +507,8 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
}
private void maybeShowRemoteCopy(ClipData clipData) {
- Intent remoteCopyIntent = IntentCreator.getRemoteCopyIntent(clipData, mContext);
+ Intent remoteCopyIntent = mIntentCreator.getRemoteCopyIntent(clipData, mContext);
+
// Only show remote copy if it's available.
PackageManager packageManager = mContext.getPackageManager();
if (packageManager.resolveActivity(
@@ -558,19 +558,19 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
private void editImage(Uri uri) {
mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED);
- mContext.startActivity(IntentCreator.getImageEditIntent(uri, mContext));
+ mContext.startActivity(mIntentCreator.getImageEditIntent(uri, mContext));
animateOut();
}
private void editText() {
mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED);
- mContext.startActivity(IntentCreator.getTextEditorIntent(mContext));
+ mContext.startActivity(mIntentCreator.getTextEditorIntent(mContext));
animateOut();
}
private void shareContent(ClipData clip) {
mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_SHARE_TAPPED);
- mContext.startActivity(IntentCreator.getShareIntent(clip, mContext));
+ mContext.startActivity(mIntentCreator.getShareIntent(clip, mContext));
animateOut();
}
@@ -717,22 +717,22 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
public void onRemoteCopyButtonTapped() {
if (clipboardSharedTransitions()) {
finish(CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED,
- IntentCreator.getRemoteCopyIntent(mClipboardModel.getClipData(), mContext));
+ mIntentCreator.getRemoteCopyIntent(mClipboardModel.getClipData(), mContext));
}
}
@Override
public void onShareButtonTapped() {
if (clipboardSharedTransitions()) {
+ Intent shareIntent =
+ mIntentCreator.getShareIntent(mClipboardModel.getClipData(), mContext);
switch (mClipboardModel.getType()) {
case TEXT:
case URI:
- finish(CLIPBOARD_OVERLAY_SHARE_TAPPED,
- IntentCreator.getShareIntent(mClipboardModel.getClipData(), mContext));
+ finish(CLIPBOARD_OVERLAY_SHARE_TAPPED, shareIntent);
break;
case IMAGE:
- finishWithSharedTransition(CLIPBOARD_OVERLAY_SHARE_TAPPED,
- IntentCreator.getShareIntent(mClipboardModel.getClipData(), mContext));
+ finishWithSharedTransition(CLIPBOARD_OVERLAY_SHARE_TAPPED, shareIntent);
break;
}
}
@@ -744,11 +744,11 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv
switch (mClipboardModel.getType()) {
case TEXT:
finish(CLIPBOARD_OVERLAY_EDIT_TAPPED,
- IntentCreator.getTextEditorIntent(mContext));
+ mIntentCreator.getTextEditorIntent(mContext));
break;
case IMAGE:
finishWithSharedTransition(CLIPBOARD_OVERLAY_EDIT_TAPPED,
- IntentCreator.getImageEditIntent(mClipboardModel.getUri(), mContext));
+ mIntentCreator.getImageEditIntent(mClipboardModel.getUri(), mContext));
break;
default:
Log.w(TAG, "Got preview tapped callback for non-editable type "
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java
new file mode 100644
index 000000000000..4b24536ad28f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.clipboardoverlay;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.res.R;
+
+import javax.inject.Inject;
+
+@SysUISingleton
+public class DefaultIntentCreator implements IntentCreator {
+ private static final String EXTRA_EDIT_SOURCE = "edit_source";
+ private static final String EDIT_SOURCE_CLIPBOARD = "clipboard";
+ private static final String REMOTE_COPY_ACTION = "android.intent.action.REMOTE_COPY";
+
+ @Inject
+ public DefaultIntentCreator() {}
+
+ public Intent getTextEditorIntent(Context context) {
+ Intent intent = new Intent(context, EditTextActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ return intent;
+ }
+
+ public Intent getShareIntent(ClipData clipData, Context context) {
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+
+ // From the ACTION_SEND docs:
+ // "If using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it should be the
+ // MIME type of the data in EXTRA_STREAM"
+ Uri uri = clipData.getItemAt(0).getUri();
+ if (uri != null) {
+ // We don't use setData here because some apps interpret this as "to:".
+ shareIntent.setType(clipData.getDescription().getMimeType(0));
+ // Include URI in ClipData also, so that grantPermission picks it up.
+ shareIntent.setClipData(new ClipData(
+ new ClipDescription(
+ "content", new String[]{clipData.getDescription().getMimeType(0)}),
+ new ClipData.Item(uri)));
+ shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
+ shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ } else {
+ shareIntent.putExtra(
+ Intent.EXTRA_TEXT, clipData.getItemAt(0).coerceToText(context).toString());
+ shareIntent.setType("text/plain");
+ }
+ Intent chooserIntent = Intent.createChooser(shareIntent, null)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ return chooserIntent;
+ }
+
+ public Intent getImageEditIntent(Uri uri, Context context) {
+ String editorPackage = context.getString(R.string.config_screenshotEditor);
+ Intent editIntent = new Intent(Intent.ACTION_EDIT);
+ if (!TextUtils.isEmpty(editorPackage)) {
+ editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
+ }
+ editIntent.setDataAndType(uri, "image/*");
+ editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ editIntent.putExtra(EXTRA_EDIT_SOURCE, EDIT_SOURCE_CLIPBOARD);
+ return editIntent;
+ }
+
+ public Intent getRemoteCopyIntent(ClipData clipData, Context context) {
+ Intent nearbyIntent = new Intent(REMOTE_COPY_ACTION);
+
+ String remoteCopyPackage = context.getString(R.string.config_remoteCopyPackage);
+ if (!TextUtils.isEmpty(remoteCopyPackage)) {
+ nearbyIntent.setComponent(ComponentName.unflattenFromString(remoteCopyPackage));
+ }
+
+ nearbyIntent.setClipData(clipData);
+ nearbyIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ return nearbyIntent;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
index a18b4c84b081..c8a6b05f090b 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,79 +17,13 @@
package com.android.systemui.clipboardoverlay;
import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.text.TextUtils;
-import com.android.systemui.res.R;
-
-class IntentCreator {
- private static final String EXTRA_EDIT_SOURCE = "edit_source";
- private static final String EDIT_SOURCE_CLIPBOARD = "clipboard";
- private static final String REMOTE_COPY_ACTION = "android.intent.action.REMOTE_COPY";
-
- static Intent getTextEditorIntent(Context context) {
- Intent intent = new Intent(context, EditTextActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- return intent;
- }
-
- static Intent getShareIntent(ClipData clipData, Context context) {
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
-
- // From the ACTION_SEND docs:
- // "If using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it should be the
- // MIME type of the data in EXTRA_STREAM"
- Uri uri = clipData.getItemAt(0).getUri();
- if (uri != null) {
- // We don't use setData here because some apps interpret this as "to:".
- shareIntent.setType(clipData.getDescription().getMimeType(0));
- // Include URI in ClipData also, so that grantPermission picks it up.
- shareIntent.setClipData(new ClipData(
- new ClipDescription(
- "content", new String[]{clipData.getDescription().getMimeType(0)}),
- new ClipData.Item(uri)));
- shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
- shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- } else {
- shareIntent.putExtra(
- Intent.EXTRA_TEXT, clipData.getItemAt(0).coerceToText(context).toString());
- shareIntent.setType("text/plain");
- }
- Intent chooserIntent = Intent.createChooser(shareIntent, null)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
- return chooserIntent;
- }
-
- static Intent getImageEditIntent(Uri uri, Context context) {
- String editorPackage = context.getString(R.string.config_screenshotEditor);
- Intent editIntent = new Intent(Intent.ACTION_EDIT);
- if (!TextUtils.isEmpty(editorPackage)) {
- editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
- }
- editIntent.setDataAndType(uri, "image/*");
- editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- editIntent.putExtra(EXTRA_EDIT_SOURCE, EDIT_SOURCE_CLIPBOARD);
- return editIntent;
- }
-
- static Intent getRemoteCopyIntent(ClipData clipData, Context context) {
- Intent nearbyIntent = new Intent(REMOTE_COPY_ACTION);
-
- String remoteCopyPackage = context.getString(R.string.config_remoteCopyPackage);
- if (!TextUtils.isEmpty(remoteCopyPackage)) {
- nearbyIntent.setComponent(ComponentName.unflattenFromString(remoteCopyPackage));
- }
-
- nearbyIntent.setClipData(clipData);
- nearbyIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- return nearbyIntent;
- }
+public interface IntentCreator {
+ Intent getTextEditorIntent(Context context);
+ Intent getShareIntent(ClipData clipData, Context context);
+ Intent getImageEditIntent(Uri uri, Context context);
+ Intent getRemoteCopyIntent(ClipData clipData, Context context);
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
index 6c10eea07ffc..c86a84b17efe 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
@@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
import static com.android.systemui.Flags.clipboardOverlayMultiuser;
import static com.android.systemui.Flags.enableViewCaptureTracing;
+import static com.android.systemui.shared.Flags.usePreferredImageEditor;
import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -32,7 +33,10 @@ import android.view.WindowManager;
import com.android.app.viewcapture.ViewCapture;
import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.systemui.clipboardoverlay.ActionIntentCreator;
import com.android.systemui.clipboardoverlay.ClipboardOverlayView;
+import com.android.systemui.clipboardoverlay.DefaultIntentCreator;
+import com.android.systemui.clipboardoverlay.IntentCreator;
import com.android.systemui.res.R;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
@@ -102,6 +106,17 @@ public interface ClipboardOverlayModule {
/* isViewCaptureEnabled= */ enableViewCaptureTracing());
}
+ @Provides
+ static IntentCreator provideIntentCreator(
+ Lazy<DefaultIntentCreator> defaultIntentCreator,
+ Lazy<ActionIntentCreator> actionIntentCreator) {
+ if (usePreferredImageEditor()) {
+ return actionIntentCreator.get();
+ } else {
+ return defaultIntentCreator.get();
+ }
+ }
+
@Qualifier
@Documented
@Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
index 097d50bb8f9d..9db7b50905f8 100644
--- a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
@@ -16,7 +16,9 @@
package com.android.systemui.common.domain.interactor
+import android.util.Log
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.PerDisplayRepository
import com.android.systemui.model.StateChange
import com.android.systemui.model.SysUiState
@@ -26,20 +28,36 @@ import javax.inject.Inject
@SysUISingleton
class SysUIStateDisplaysInteractor
@Inject
-constructor(private val sysUIStateRepository: PerDisplayRepository<SysUiState>) {
+constructor(
+ private val sysUIStateRepository: PerDisplayRepository<SysUiState>,
+ private val displayRepository: DisplayRepository,
+) {
/**
* Sets the flags on the given [targetDisplayId] based on the [stateChanges], while making sure
* that those flags are not set in any other display.
*/
fun setFlagsExclusivelyToDisplay(targetDisplayId: Int, stateChanges: StateChange) {
- sysUIStateRepository.forEachInstance { displayId, instance ->
- if (displayId == targetDisplayId) {
- stateChanges.applyTo(instance)
- } else {
- stateChanges.clearAllChangedFlagsIn(instance)
- }
+ if (SysUiState.DEBUG) {
+ Log.d(TAG, "Setting flags $stateChanges only for display $targetDisplayId")
}
+ displayRepository.displays.value
+ .mapNotNull { sysUIStateRepository[it.displayId] }
+ .apply {
+ // Let's first modify all states, without committing changes ...
+ forEach { displaySysUIState ->
+ if (displaySysUIState.displayId == targetDisplayId) {
+ stateChanges.applyTo(displaySysUIState)
+ } else {
+ stateChanges.clearFrom(displaySysUIState)
+ }
+ }
+ // ... And commit changes at the end
+ forEach { sysuiState -> sysuiState.commitUpdate() }
+ }
}
-}
+ private companion object {
+ const val TAG = "SysUIStateInteractor"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt
index 13f6bba01135..07cc136e6bc6 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt
@@ -147,7 +147,7 @@ constructor(
*/
fun create(
context: Context,
- configurationController: ConfigurationController
+ configurationController: ConfigurationController,
): ConfigurationStateImpl
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java
index e456310febfd..4be9601f4277 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java
@@ -102,7 +102,7 @@ public class DeviceInactiveCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index d7859c985c7b..62a98d7a48ea 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -367,11 +367,24 @@ constructor(
/** See [CommunalSettingsInteractor.isV2FlagEnabled] */
fun v2FlagEnabled(): Boolean = communalSettingsInteractor.isV2FlagEnabled()
- val swipeToHubEnabled: StateFlow<Boolean> by lazy {
+ val swipeToHubEnabled: Flow<Boolean> by lazy {
+ val inAllowedDeviceState =
+ if (swipeToHub) {
+ MutableStateFlow(true)
+ } else if (v2FlagEnabled()) {
+ communalInteractor.shouldShowCommunal
+ } else {
+ MutableStateFlow(false)
+ }
+
if (v2FlagEnabled()) {
- communalInteractor.shouldShowCommunal
+ val inAllowedKeyguardState =
+ keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
+ it.to == KeyguardState.LOCKSCREEN || it.to == KeyguardState.GLANCEABLE_HUB
+ }
+ allOf(inAllowedDeviceState, inAllowedKeyguardState)
} else {
- MutableStateFlow(swipeToHub)
+ inAllowedDeviceState
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt
index 69da67e055fe..1e7bec257432 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt
@@ -68,10 +68,4 @@ constructor(
emptyFlow()
}
}
-
- /** Triggered if a face failure occurs regardless of the mode. */
- val faceFailure: Flow<FailedFaceAuthenticationStatus> =
- deviceEntryFaceAuthInteractor.authenticationStatus.filterIsInstance<
- FailedFaceAuthenticationStatus
- >()
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt
index 38e0503440f9..09936839c590 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardBypassInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.util.kotlin.FlowDumperImpl
@@ -49,8 +48,6 @@ class DeviceEntryHapticsInteractor
constructor(
biometricSettingsRepository: BiometricSettingsRepository,
deviceEntryBiometricAuthInteractor: DeviceEntryBiometricAuthInteractor,
- deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor,
- keyguardBypassInteractor: KeyguardBypassInteractor,
deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
deviceEntrySourceInteractor: DeviceEntrySourceInteractor,
fingerprintPropertyRepository: FingerprintPropertyRepository,
@@ -83,7 +80,12 @@ constructor(
emit(recentPowerButtonPressThresholdMs * -1L - 1L)
}
- private val playHapticsOnDeviceEntry: Flow<Boolean> =
+ /**
+ * Indicates when success haptics should play when the device is entered. This always occurs on
+ * successful fingerprint authentications. It also occurs on successful face authentication but
+ * only if the lockscreen is bypassed.
+ */
+ val playSuccessHapticOnDeviceEntry: Flow<Unit> =
deviceEntrySourceInteractor.deviceEntryFromBiometricSource
.sample(
combine(
@@ -93,29 +95,17 @@ constructor(
::Triple,
)
)
- .map { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) ->
+ .filter { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) ->
val sideFpsAllowsHaptic =
!powerButtonDown &&
systemClock.uptimeMillis() - lastPowerButtonWakeup >
recentPowerButtonPressThresholdMs
val allowHaptic = !sideFpsEnrolled || sideFpsAllowsHaptic
if (!allowHaptic) {
- logger.d(
- "Skip success entry haptic from power button. Recent power button press or button is down."
- )
+ logger.d("Skip success haptic. Recent power button press or button is down.")
}
allowHaptic
}
-
- private val playHapticsOnFaceAuthSuccessAndBypassDisabled: Flow<Boolean> =
- deviceEntryFaceAuthInteractor.isAuthenticated
- .filter { it }
- .sample(keyguardBypassInteractor.isBypassAvailable)
- .map { !it }
-
- val playSuccessHaptic: Flow<Unit> =
- merge(playHapticsOnDeviceEntry, playHapticsOnFaceAuthSuccessAndBypassDisabled)
- .filter { it }
// map to Unit
.map {}
.dumpWhileCollecting("playSuccessHaptic")
@@ -123,7 +113,7 @@ constructor(
private val playErrorHapticForBiometricFailure: Flow<Unit> =
merge(
deviceEntryFingerprintAuthInteractor.fingerprintFailure,
- deviceEntryBiometricAuthInteractor.faceFailure,
+ deviceEntryBiometricAuthInteractor.faceOnlyFaceFailure,
)
// map to Unit
.map {}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
index 04f245e91914..d27e33e53dbb 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
@@ -91,18 +91,6 @@ interface PerDisplayRepository<T> {
/** Debug name for this repository, mainly for tracing and logging. */
val debugName: String
-
- /**
- * Invokes the specified action on each instance held by this repository.
- *
- * The action will receive the displayId and the instance associated with that display.
- * If there is no instance for the display, the action is not called.
- */
- fun forEachInstance(action: (Int, T) -> Unit) {
- displayIds.forEach { displayId ->
- get(displayId)?.let { instance -> action(displayId, instance) }
- }
- }
}
/**
@@ -138,10 +126,11 @@ constructor(
get() = perDisplayInstances.keys
private suspend fun start() {
- dumpManager.registerDumpable(this)
+ dumpManager.registerNormalDumpable("PerDisplayRepository-${debugName}", this)
displayRepository.displayIds.collectLatest { displayIds ->
val toRemove = perDisplayInstances.keys - displayIds
toRemove.forEach { displayId ->
+ Log.d(TAG, "<$debugName> destroying instance for displayId=$displayId.")
perDisplayInstances.remove(displayId)?.let { instance ->
(instanceProvider as? PerDisplayInstanceProviderWithTeardown)?.destroyInstance(
instance
@@ -159,6 +148,7 @@ constructor(
// If it doesn't exist, create it and put it in the map.
return perDisplayInstances.computeIfAbsent(displayId) { key ->
+ Log.d(TAG, "<$debugName> creating instance for displayId=$key, as it wasn't available.")
val instance =
traceSection({ "creating instance of $debugName for displayId=$key" }) {
instanceProvider.createInstance(key)
@@ -194,8 +184,13 @@ constructor(
* Provides an instance of a given class **only** for the default display, even if asked for another
* display.
*
- * This is useful in case of flag refactors: it can be provided instead of an instance of
+ * This is useful in case of **flag refactors**: it can be provided instead of an instance of
* [PerDisplayInstanceRepositoryImpl] when a flag related to multi display refactoring is off.
+ *
+ * Note that this still requires all instances to be provided by a [PerDisplayInstanceProvider]. If
+ * you want to provide an existing instance instead for the default display, either implement it in
+ * a custom [PerDisplayInstanceProvider] (e.g. inject it in the constructor and return it if the
+ * displayId is zero), or use [SingleInstanceRepositoryImpl].
*/
class DefaultDisplayOnlyInstanceRepositoryImpl<T>(
override val debugName: String,
@@ -208,3 +203,18 @@ class DefaultDisplayOnlyInstanceRepositoryImpl<T>(
override fun get(displayId: Int): T? = lazyDefaultDisplayInstance
}
+
+/**
+ * Always returns [instance] for any display.
+ *
+ * This can be used to provide a single instance based on a flag value during a refactor. Similar to
+ * [DefaultDisplayOnlyInstanceRepositoryImpl], but also avoids creating the
+ * [PerDisplayInstanceProvider]. This is useful when you want to provide an existing instance only,
+ * without even instantiating a [PerDisplayInstanceProvider].
+ */
+class SingleInstanceRepositoryImpl<T>(override val debugName: String, private val instance: T) :
+ PerDisplayRepository<T> {
+ override val displayIds: Set<Int> = setOf(Display.DEFAULT_DISPLAY)
+
+ override fun get(displayId: Int): T? = instance
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 12718e8bd119..9edd9dc056c7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -94,6 +94,7 @@ import java.util.function.Consumer;
public class DozeSensors {
private static final String TAG = "DozeSensors";
private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
+ private static final String KEY_DOZE_PULSE_ON_AUTH = "doze_pulse_on_auth";
private final AsyncSensorManager mSensorManager;
private final AmbientDisplayConfiguration mConfig;
@@ -241,7 +242,7 @@ public class DozeSensors {
),
new TriggerSensor(
findSensor(config.udfpsLongPressSensorType()),
- "doze_pulse_on_auth",
+ KEY_DOZE_PULSE_ON_AUTH,
true /* settingDef */,
udfpsLongPressConfigured(),
DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
@@ -421,6 +422,18 @@ public class DozeSensors {
&& (!s.mRequiresTouchscreen || mListeningTouchScreenSensors)
&& (!s.mRequiresProx || mListeningProxSensors)
&& (!s.mRequiresAod || mListeningAodOnlySensors);
+
+ //AOD might be turned off in visual because of BetterySaver or isAlwaysOnSuppressed(),
+ //but AOD isn't really turned off, in these cases, udfpsLongPressSensor should be
+ //unregistered.
+ if (!mListeningAodOnlySensors && KEY_DOZE_PULSE_ON_AUTH.equals(s.mSetting)) {
+ if (mConfig.alwaysOnEnabled(mSelectedUserInteractor.getSelectedUserId())
+ && !mConfig.screenOffUdfpsEnabled(
+ mSelectedUserInteractor.getSelectedUserId())) {
+ listen = false;
+ }
+ }
+
s.setListening(listen);
if (listen) {
anyListening = true;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
index d81949d08a66..c17094b7456c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
@@ -63,7 +63,7 @@ public class AssistantAttentionCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
index c7fe1e1e754b..fb4ed1419688 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
@@ -63,7 +63,7 @@ public class DreamCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt b/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
index ca157afb7721..293461daef7b 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
@@ -91,6 +91,7 @@ object RefactorFlagUtils {
* }
* ````
*/
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
inline fun unsafeAssertInNewMode(isEnabled: Boolean, flagName: Any) =
check(isEnabled) { "New code path not supported when $flagName is disabled." }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index 54e27a61ac78..04a0630771df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -88,10 +88,7 @@ constructor(
private fun createDialog(): Dialog {
return dialogFactory.create(dialogDelegate = ShortcutCustomizationDialogDelegate()) { dialog
->
- val uiState by
- viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle(
- initialValue = ShortcutCustomizationUiState.Inactive
- )
+ val uiState by viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle()
val coroutineScope = rememberCoroutineScope()
ShortcutCustomizationDialog(
uiState = uiState,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
index 7e0fa2f125b0..c601e6e0baf6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -409,6 +409,7 @@ private fun Title(title: String) {
color = MaterialTheme.colorScheme.onSurface,
lineHeight = 32.sp,
fontWeight = FontWeight.W400,
+ textAlign = TextAlign.Center,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt
index 1febc79b8241..bc65ad476c37 100644
--- a/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt
@@ -42,7 +42,7 @@ constructor(
when (event.keyCode) {
KeyEvent.KEYCODE_BACK -> {
- if (event.handleAction()) {
+ if (!backActionInteractor.isBackCallbackRegistered() && event.handleAction()) {
backActionInteractor.onBackRequested()
}
return true
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 2c5bacb62e72..70e2413386e3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -196,6 +196,9 @@ public class WorkLockActivity extends Activity {
confirmCredentialIntent.putExtra(Intent.EXTRA_INTENT, target.getIntentSender());
}
+ String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ confirmCredentialIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+
// WorkLockActivity is started as a task overlay, so unless credential confirmation is also
// started as an overlay, it won't be visible.
final ActivityOptions launchOptions = ActivityOptions.makeBasic();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 45801ba3517a..aeb327035c79 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -333,7 +333,7 @@ object KeyguardRootViewBinder {
if (deviceEntryHapticsInteractor != null && vibratorHelper != null) {
launch {
- deviceEntryHapticsInteractor.playSuccessHaptic.collect {
+ deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry.collect {
if (msdlFeedback()) {
msdlPlayer?.playToken(
MSDLToken.UNLOCK,
@@ -474,7 +474,7 @@ object KeyguardRootViewBinder {
val transition = blueprintViewModel.currentTransition.value
val shouldAnimate = transition != null && transition.config.type.animateNotifChanges
if (prevTransition == transition && shouldAnimate) {
- logger.w("Skipping; layout during transition")
+ logger.w("Skipping onNotificationContainerBoundsChanged during transition")
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index faa6c52162ce..a85b9b04c1ce 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -327,7 +327,8 @@ public class LogModule {
@SysUISingleton
@KeyguardBlueprintLog
public static LogBuffer provideKeyguardBlueprintLog(LogBufferFactory factory) {
- return factory.create("KeyguardBlueprintLog", 100);
+ // TODO(b/389987229): Reduce back to 100
+ return factory.create("KeyguardBlueprintLog", 1000);
}
/**
@@ -337,7 +338,8 @@ public class LogModule {
@SysUISingleton
@KeyguardClockLog
public static LogBuffer provideKeyguardClockLog(LogBufferFactory factory) {
- return factory.create("KeyguardClockLog", 100);
+ // TODO(b/389987229): Reduce back to 100
+ return factory.create("KeyguardClockLog", 1000);
}
/**
@@ -347,7 +349,8 @@ public class LogModule {
@SysUISingleton
@KeyguardSmallClockLog
public static LogBuffer provideKeyguardSmallClockLog(LogBufferFactory factory) {
- return factory.create("KeyguardSmallClockLog", 100);
+ // TODO(b/389987229): Reduce back to 100
+ return factory.create("KeyguardSmallClockLog", 1000);
}
/**
@@ -357,7 +360,8 @@ public class LogModule {
@SysUISingleton
@KeyguardLargeClockLog
public static LogBuffer provideKeyguardLargeClockLog(LogBufferFactory factory) {
- return factory.create("KeyguardLargeClockLog", 100);
+ // TODO(b/389987229): Reduce back to 100
+ return factory.create("KeyguardLargeClockLog", 1000);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
index 4c1da0198498..57d709835b2c 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
@@ -54,7 +54,6 @@ constructor(
job?.cancel()
}
- override fun getStartStrategy(): Int {
- return START_EAGERLY
- }
+ override val startStrategy: Int
+ get() = START_EAGERLY
}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java
index 7f21d0707f63..5ec81a9a94a1 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java
@@ -131,7 +131,7 @@ public class ForceLowLightCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java
index e91be5028777..c1a24e7e020e 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java
@@ -54,7 +54,7 @@ public class LowLightCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
// As this condition keeps the lowlight sensor active, it should only run when needed.
return START_WHEN_NEEDED;
}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java
index fd6ce1762a28..81572554cb86 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java
@@ -70,7 +70,7 @@ public class ScreenSaverEnabledCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
deleted file mode 100644
index 0cb36edfd382..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.domain.pipeline.interactor
-
-import android.content.Context
-import android.content.Intent
-import android.provider.Settings
-import android.util.Log
-import androidx.annotation.VisibleForTesting
-import com.android.internal.jank.InteractionJankMonitor
-import com.android.systemui.animation.Expandable
-import com.android.systemui.broadcast.BroadcastSender
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.media.controls.data.repository.MediaFilterRepository
-import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
-import com.android.systemui.media.controls.shared.model.MediaRecModel
-import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
-import com.android.systemui.plugins.ActivityStarter
-import java.net.URISyntaxException
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-
-/** Encapsulates business logic for media recommendation */
-@SysUISingleton
-class MediaRecommendationsInteractor
-@Inject
-constructor(
- @Application applicationScope: CoroutineScope,
- @Application private val applicationContext: Context,
- private val repository: MediaFilterRepository,
- private val mediaDataProcessor: MediaDataProcessor,
- private val broadcastSender: BroadcastSender,
- private val activityStarter: ActivityStarter,
-) {
-
- val recommendations: Flow<MediaRecommendationsModel> =
- repository.smartspaceMediaData.map { toRecommendationsModel(it) }.distinctUntilChanged()
-
- /** Indicates whether the recommendations card is active. */
- val isActive: StateFlow<Boolean> =
- repository.smartspaceMediaData
- .map { it.isActive }
- .distinctUntilChanged()
- .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
-
- fun removeMediaRecommendations(key: String, dismissIntent: Intent?, delayMs: Long) {
- mediaDataProcessor.dismissSmartspaceRecommendation(key, delayMs)
- if (dismissIntent == null) {
- Log.w(TAG, "Cannot create dismiss action click action: extras missing dismiss_intent.")
- return
- }
-
- val className = dismissIntent.component?.className
- if (className == EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME) {
- // Dismiss the card Smartspace data through Smartspace trampoline activity.
- applicationContext.startActivity(dismissIntent)
- } else {
- broadcastSender.sendBroadcast(dismissIntent)
- }
- }
-
- fun startSettings() {
- activityStarter.startActivity(SETTINGS_INTENT, /* dismissShade= */ true)
- }
-
- fun startClickIntent(expandable: Expandable, intent: Intent) {
- if (shouldActivityOpenInForeground(intent)) {
- // Request to unlock the device if the activity needs to be opened in foreground.
- activityStarter.postStartActivityDismissingKeyguard(
- intent,
- 0 /* delay */,
- expandable.activityTransitionController(
- InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER
- ),
- )
- } else {
- // Otherwise, open the activity in background directly.
- applicationContext.startActivity(intent)
- }
- }
-
- /** Returns if the action will open the activity in foreground. */
- private fun shouldActivityOpenInForeground(intent: Intent): Boolean {
- val intentString = intent.extras?.getString(EXTRAS_SMARTSPACE_INTENT) ?: return false
- try {
- val wrapperIntent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME)
- return wrapperIntent.getBooleanExtra(KEY_SMARTSPACE_OPEN_IN_FOREGROUND, false)
- } catch (e: URISyntaxException) {
- Log.wtf(TAG, "Failed to create intent from URI: $intentString")
- e.printStackTrace()
- }
- return false
- }
-
- private fun toRecommendationsModel(data: SmartspaceMediaData): MediaRecommendationsModel {
- val mediaRecs = ArrayList<MediaRecModel>()
- data.recommendations.forEach {
- with(it) { mediaRecs.add(MediaRecModel(intent, title, subtitle, icon, extras)) }
- }
- return with(data) {
- MediaRecommendationsModel(
- key = targetId,
- uid = getUid(applicationContext),
- packageName = packageName,
- instanceId = instanceId,
- appName = getAppName(applicationContext),
- dismissIntent = dismissIntent,
- areRecommendationsValid = isValid(),
- mediaRecs = mediaRecs,
- )
- }
- }
-
- fun switchToMediaControl(packageName: String) {
- repository.setMediaFromRecPackageName(packageName)
- }
-
- companion object {
-
- private const val TAG = "MediaRecommendationsInteractor"
-
- // TODO (b/237284176) : move AGSA reference out.
- private const val EXTRAS_SMARTSPACE_INTENT =
- "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT"
- @VisibleForTesting
- const val EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME =
- "com.google.android.apps.gsa.staticplugins.opa.smartspace." +
- "ExportedSmartspaceTrampolineActivity"
-
- private const val KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND"
-
- private val SETTINGS_INTENT = Intent(Settings.ACTION_MEDIA_CONTROLS_SETTINGS)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
deleted file mode 100644
index 4877d18de7ab..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.binder
-
-import android.app.WallpaperColors
-import android.content.Context
-import android.content.res.ColorStateList
-import android.content.res.Configuration
-import android.graphics.Bitmap
-import android.graphics.Color
-import android.graphics.Matrix
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.ColorDrawable
-import android.graphics.drawable.Drawable
-import android.graphics.drawable.GradientDrawable
-import android.graphics.drawable.Icon
-import android.graphics.drawable.LayerDrawable
-import android.os.Trace
-import android.util.TypedValue
-import android.view.View
-import android.view.ViewGroup
-import androidx.appcompat.content.res.AppCompatResources
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.animation.Expandable
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.media.controls.shared.model.NUM_REQUIRED_RECOMMENDATIONS
-import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
-import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
-import com.android.systemui.media.controls.ui.animation.textSecondaryFromScheme
-import com.android.systemui.media.controls.ui.controller.MediaViewController
-import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
-import com.android.systemui.media.controls.ui.viewmodel.MediaRecViewModel
-import com.android.systemui.media.controls.ui.viewmodel.MediaRecommendationsViewModel
-import com.android.systemui.media.controls.ui.viewmodel.MediaRecsCardViewModel
-import com.android.systemui.monet.ColorScheme
-import com.android.systemui.monet.Style
-import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.res.R
-import com.android.systemui.util.animation.TransitionLayout
-import kotlin.math.min
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.collectLatest
-import com.android.app.tracing.coroutines.launchTraced as launch
-import kotlinx.coroutines.withContext
-
-private const val TAG = "MediaRecommendationsViewBinder"
-private const val MEDIA_REC_SCRIM_START_ALPHA = 0.15f
-private const val MEDIA_REC_SCRIM_END_ALPHA = 1.0f
-
-object MediaRecommendationsViewBinder {
-
- /** Binds recommendations view holder to the given view-model */
- fun bind(
- viewHolder: RecommendationViewHolder,
- viewModel: MediaRecommendationsViewModel,
- mediaViewController: MediaViewController,
- falsingManager: FalsingManager,
- backgroundDispatcher: CoroutineDispatcher,
- mainDispatcher: CoroutineDispatcher,
- ) {
- mediaViewController.recsConfigurationChangeListener = this::updateRecommendationsVisibility
- val cardView = viewHolder.recommendations
- cardView.repeatWhenAttached {
- lifecycleScope.launch {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- launch {
- viewModel.mediaRecsCard.collectLatest { viewModel ->
- viewModel?.let {
- bindRecsCard(
- viewHolder,
- it,
- mediaViewController,
- falsingManager,
- backgroundDispatcher,
- mainDispatcher,
- )
- }
- }
- }
- }
- }
- }
- }
-
- suspend fun bindRecsCard(
- viewHolder: RecommendationViewHolder,
- viewModel: MediaRecsCardViewModel,
- viewController: MediaViewController,
- falsingManager: FalsingManager,
- backgroundDispatcher: CoroutineDispatcher,
- mainDispatcher: CoroutineDispatcher,
- ) {
- // Set up media control location and its listener.
- viewModel.onLocationChanged(viewController.currentEndLocation)
- viewController.locationChangeListener = viewModel.onLocationChanged
-
- // Bind main card.
- viewHolder.recommendations.contentDescription =
- viewModel.contentDescription.invoke(viewController.isGutsVisible)
-
- viewHolder.recommendations.setOnClickListener {
- if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
- viewModel.onClicked(Expandable.fromView(it))
- }
-
- viewHolder.recommendations.setOnLongClickListener {
- if (falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY))
- return@setOnLongClickListener true
- if (!viewController.isGutsVisible) {
- openGuts(viewHolder, viewModel, viewController)
- } else {
- closeGuts(viewHolder, viewModel, viewController)
- }
- return@setOnLongClickListener true
- }
-
- // Bind colors
- val appIcon = viewModel.mediaRecs.first().appIcon
- fetchAndUpdateColors(viewHolder, appIcon, backgroundDispatcher, mainDispatcher)
- // Bind all recommendations.
- bindRecommendationsList(
- viewHolder,
- viewModel.mediaRecs,
- falsingManager,
- backgroundDispatcher,
- mainDispatcher,
- )
- updateRecommendationsVisibility(viewController, viewHolder.recommendations)
-
- // Set visibility of recommendations.
- val expandedSet: ConstraintSet = viewController.expandedLayout
- val collapsedSet: ConstraintSet = viewController.collapsedLayout
- viewHolder.mediaTitles.forEach {
- setVisibleAndAlpha(expandedSet, it.id, viewModel.areTitlesVisible)
- setVisibleAndAlpha(collapsedSet, it.id, viewModel.areTitlesVisible)
- }
- viewHolder.mediaSubtitles.forEach {
- setVisibleAndAlpha(expandedSet, it.id, viewModel.areSubtitlesVisible)
- setVisibleAndAlpha(collapsedSet, it.id, viewModel.areSubtitlesVisible)
- }
-
- bindRecommendationsGuts(viewHolder, viewModel, viewController, falsingManager)
-
- viewController.refreshState()
- }
-
- private fun bindRecommendationsGuts(
- viewHolder: RecommendationViewHolder,
- viewModel: MediaRecsCardViewModel,
- viewController: MediaViewController,
- falsingManager: FalsingManager,
- ) {
- val gutsViewHolder = viewHolder.gutsViewHolder
- val gutsViewModel = viewModel.gutsMenu
-
- gutsViewHolder.gutsText.text = gutsViewModel.gutsText
- gutsViewHolder.dismissText.visibility = View.VISIBLE
- gutsViewHolder.dismiss.isEnabled = true
- gutsViewHolder.dismiss.setOnClickListener {
- if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
- closeGuts(viewHolder, viewModel, viewController)
- gutsViewModel.onDismissClicked()
- }
-
- gutsViewHolder.cancelText.background = gutsViewModel.cancelTextBackground
- gutsViewHolder.cancel.setOnClickListener {
- if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
- closeGuts(viewHolder, viewModel, viewController)
- }
- }
-
- gutsViewHolder.settings.setOnClickListener {
- if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
- gutsViewModel.onSettingsClicked.invoke()
- }
- }
-
- gutsViewHolder.setDismissible(gutsViewModel.isDismissEnabled)
- }
-
- private suspend fun bindRecommendationsList(
- viewHolder: RecommendationViewHolder,
- mediaRecs: List<MediaRecViewModel>,
- falsingManager: FalsingManager,
- backgroundDispatcher: CoroutineDispatcher,
- mainDispatcher: CoroutineDispatcher,
- ) {
- mediaRecs.forEachIndexed { index, mediaRecViewModel ->
- if (index >= NUM_REQUIRED_RECOMMENDATIONS) return@forEachIndexed
-
- val appIconView = viewHolder.mediaAppIcons[index]
- appIconView.clearColorFilter()
- appIconView.setImageDrawable(mediaRecViewModel.appIcon)
-
- val mediaCoverContainer = viewHolder.mediaCoverContainers[index]
- mediaCoverContainer.setOnClickListener {
- if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
- mediaRecViewModel.onClicked(Expandable.fromView(it), index)
- }
- mediaCoverContainer.setOnLongClickListener {
- if (falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY))
- return@setOnLongClickListener true
- (it.parent as View).performLongClick()
- return@setOnLongClickListener true
- }
-
- val mediaCover = viewHolder.mediaCoverItems[index]
- bindRecommendationArtwork(
- mediaCover.context,
- viewHolder,
- mediaRecViewModel,
- index,
- backgroundDispatcher,
- mainDispatcher,
- )
- mediaCover.contentDescription = mediaRecViewModel.contentDescription
-
- val title = viewHolder.mediaTitles[index]
- title.text = mediaRecViewModel.title
-
- val subtitle = viewHolder.mediaSubtitles[index]
- subtitle.text = mediaRecViewModel.subtitle
-
- val progressBar = viewHolder.mediaProgressBars[index]
- progressBar.progress = mediaRecViewModel.progress
- if (mediaRecViewModel.progress == 0) {
- progressBar.visibility = View.GONE
- }
- }
- }
-
- private fun openGuts(
- viewHolder: RecommendationViewHolder,
- viewModel: MediaRecsCardViewModel,
- mediaViewController: MediaViewController,
- ) {
- viewHolder.marquee(true, MediaViewController.GUTS_ANIMATION_DURATION)
- mediaViewController.openGuts()
- viewHolder.recommendations.contentDescription = viewModel.contentDescription.invoke(true)
- viewModel.onLongClicked.invoke()
- }
-
- private fun closeGuts(
- viewHolder: RecommendationViewHolder,
- mediaRecsCardViewModel: MediaRecsCardViewModel,
- mediaViewController: MediaViewController,
- ) {
- viewHolder.marquee(false, MediaViewController.GUTS_ANIMATION_DURATION)
- mediaViewController.closeGuts(false)
- viewHolder.recommendations.contentDescription =
- mediaRecsCardViewModel.contentDescription.invoke(false)
- }
-
- private fun setVisibleAndAlpha(set: ConstraintSet, resId: Int, visible: Boolean) {
- set.setVisibility(resId, if (visible) ConstraintSet.VISIBLE else ConstraintSet.GONE)
- set.setAlpha(resId, if (visible) 1.0f else 0.0f)
- }
-
- fun updateRecommendationsVisibility(
- mediaViewController: MediaViewController,
- cardView: TransitionLayout,
- ) {
- val fittedRecsNum = getNumberOfFittedRecommendations(cardView.context)
- val expandedSet = mediaViewController.expandedLayout
- val collapsedSet = mediaViewController.collapsedLayout
- val mediaCoverContainers = getMediaCoverContainers(cardView)
- // Hide media cover that cannot fit in the recommendation card.
- mediaCoverContainers.forEachIndexed { index, container ->
- setVisibleAndAlpha(expandedSet, container.id, index < fittedRecsNum)
- setVisibleAndAlpha(collapsedSet, container.id, index < fittedRecsNum)
- }
- }
-
- private fun getMediaCoverContainers(cardView: TransitionLayout): List<ViewGroup> {
- return listOf<ViewGroup>(
- cardView.requireViewById(R.id.media_cover1_container),
- cardView.requireViewById(R.id.media_cover2_container),
- cardView.requireViewById(R.id.media_cover3_container),
- )
- }
-
- private fun getNumberOfFittedRecommendations(context: Context): Int {
- val res = context.resources
- val config = res.configuration
- val defaultDpWidth = res.getInteger(R.integer.default_qs_media_rec_width_dp)
- val recCoverWidth =
- (res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width) +
- res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2)
-
- // On landscape, media controls should take half of the screen width.
- val displayAvailableDpWidth =
- if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- config.screenWidthDp / 2
- } else {
- config.screenWidthDp
- }
- val fittedNum =
- if (displayAvailableDpWidth > defaultDpWidth) {
- val recCoverDefaultWidth =
- res.getDimensionPixelSize(R.dimen.qs_media_rec_default_width)
- recCoverDefaultWidth / recCoverWidth
- } else {
- val displayAvailableWidth =
- TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- displayAvailableDpWidth.toFloat(),
- res.displayMetrics,
- )
- .toInt()
- displayAvailableWidth / recCoverWidth
- }
- return min(fittedNum.toDouble(), NUM_REQUIRED_RECOMMENDATIONS.toDouble()).toInt()
- }
-
- private suspend fun bindRecommendationArtwork(
- context: Context,
- viewHolder: RecommendationViewHolder,
- viewModel: MediaRecViewModel,
- index: Int,
- backgroundDispatcher: CoroutineDispatcher,
- mainDispatcher: CoroutineDispatcher,
- ) {
- val traceCookie = viewHolder.hashCode()
- val traceName = "MediaRecommendationsViewBinder#bindRecommendationArtwork"
- Trace.beginAsyncSection(traceName, traceCookie)
-
- // Capture width & height from views in foreground for artwork scaling in background
- val width = context.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
- val height =
- context.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_height_expanded)
-
- withContext(backgroundDispatcher) {
- val artwork =
- getRecCoverBackground(
- context,
- viewModel.albumIcon,
- width,
- height,
- backgroundDispatcher,
- )
- withContext(mainDispatcher) {
- val mediaCover = viewHolder.mediaCoverItems[index]
- val coverMatrix = Matrix(mediaCover.imageMatrix)
- coverMatrix.postScale(1.25f, 1.25f, 0.5f * width, 0.5f * height)
- mediaCover.imageMatrix = coverMatrix
- mediaCover.setImageDrawable(artwork)
- }
- }
- }
-
- /** Returns the recommendation album cover of [width]x[height] size. */
- private suspend fun getRecCoverBackground(
- context: Context,
- icon: Icon?,
- width: Int,
- height: Int,
- backgroundDispatcher: CoroutineDispatcher,
- ): Drawable =
- withContext(backgroundDispatcher) {
- return@withContext MediaArtworkHelper.getWallpaperColor(
- context,
- backgroundDispatcher,
- icon,
- TAG,
- )
- ?.let { wallpaperColors ->
- addGradientToRecommendationAlbum(
- context,
- icon!!,
- ColorScheme(wallpaperColors, true, Style.CONTENT),
- width,
- height,
- )
- } ?: ColorDrawable(Color.TRANSPARENT)
- }
-
- private fun addGradientToRecommendationAlbum(
- context: Context,
- artworkIcon: Icon,
- mutableColorScheme: ColorScheme,
- width: Int,
- height: Int,
- ): LayerDrawable {
- // First try scaling rec card using bitmap drawable.
- // If returns null, set drawable bounds.
- val albumArt =
- getScaledRecommendationCover(context, artworkIcon, width, height)
- ?: MediaArtworkHelper.getScaledBackground(context, artworkIcon, width, height)
- val gradient =
- AppCompatResources.getDrawable(context, R.drawable.qs_media_rec_scrim)?.mutate()
- as GradientDrawable
- return MediaArtworkHelper.setUpGradientColorOnDrawable(
- albumArt,
- gradient,
- mutableColorScheme,
- MEDIA_REC_SCRIM_START_ALPHA,
- MEDIA_REC_SCRIM_END_ALPHA,
- )
- }
-
- /** Returns a [Drawable] of a given [artworkIcon] scaled to [width]x[height] size, . */
- private fun getScaledRecommendationCover(
- context: Context,
- artworkIcon: Icon,
- width: Int,
- height: Int,
- ): Drawable? {
- check(width > 0) { "Width must be a positive number but was $width" }
- check(height > 0) { "Height must be a positive number but was $height" }
-
- return if (
- artworkIcon.type == Icon.TYPE_BITMAP || artworkIcon.type == Icon.TYPE_ADAPTIVE_BITMAP
- ) {
- artworkIcon.bitmap?.let {
- val bitmap = Bitmap.createScaledBitmap(it, width, height, false)
- BitmapDrawable(context.resources, bitmap)
- }
- } else {
- null
- }
- }
-
- private suspend fun fetchAndUpdateColors(
- viewHolder: RecommendationViewHolder,
- appIcon: Drawable,
- backgroundDispatcher: CoroutineDispatcher,
- mainDispatcher: CoroutineDispatcher,
- ) =
- withContext(backgroundDispatcher) {
- val colorScheme =
- ColorScheme(WallpaperColors.fromDrawable(appIcon), /* darkTheme= */ true)
- withContext(mainDispatcher) {
- val backgroundColor = surfaceFromScheme(colorScheme)
- val textPrimaryColor = textPrimaryFromScheme(colorScheme)
- val textSecondaryColor = textSecondaryFromScheme(colorScheme)
-
- viewHolder.cardTitle.setTextColor(textPrimaryColor)
- viewHolder.recommendations.setBackgroundTintList(
- ColorStateList.valueOf(backgroundColor)
- )
-
- viewHolder.mediaTitles.forEach { it.setTextColor(textPrimaryColor) }
- viewHolder.mediaSubtitles.forEach { it.setTextColor(textSecondaryColor) }
- viewHolder.mediaProgressBars.forEach {
- it.progressTintList = ColorStateList.valueOf(textPrimaryColor)
- }
-
- viewHolder.gutsViewHolder.setColors(colorScheme)
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index 7b1ae57ed421..ac6343c6bb64 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -61,14 +61,12 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.ui.binder.MediaControlViewBinder
-import com.android.systemui.media.controls.ui.binder.MediaRecommendationsViewBinder
import com.android.systemui.media.controls.ui.util.MediaViewModelCallback
import com.android.systemui.media.controls.ui.util.MediaViewModelListUpdateCallback
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaScrollView
import com.android.systemui.media.controls.ui.view.MediaViewHolder
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
import com.android.systemui.media.controls.ui.viewmodel.MediaCarouselViewModel
import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -478,41 +476,10 @@ constructor(
MediaPlayerData.isSwipedAway = false
}
- override fun onSmartspaceMediaDataLoaded(
- key: String,
- data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- ) {
- debugLogger.logRecommendationLoaded(key, data.isActive)
- // Log the case where the hidden media carousel with the existed inactive resume
- // media is shown by the Smartspace signal.
- if (data.isActive) {
- addSmartspaceMediaRecommendations(key, data, shouldPrioritize)
- } else {
- // Handle update to inactive as a removal
- onSmartspaceMediaDataRemoved(data.targetId, immediately = true)
- }
- MediaPlayerData.isSwipedAway = false
- }
-
override fun onMediaDataRemoved(key: String, userInitiated: Boolean) {
debugLogger.logMediaRemoved(key, userInitiated)
removePlayer(key, userInitiated = userInitiated)
}
-
- override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
- debugLogger.logRecommendationRemoved(key, immediately)
- if (immediately || isReorderingAllowed) {
- removePlayer(key)
- if (!immediately) {
- // Although it wasn't requested, we were able to process the removal
- // immediately since reordering is allowed. So, notify hosts to update
- updateHostVisibility()
- }
- } else {
- keysNeedRemoval.add(key)
- }
- }
}
)
}
@@ -655,22 +622,6 @@ constructor(
mediaContent.addView(viewHolder.player, position)
controllerById[commonViewModel.instanceId.toString()] = viewController
}
- is MediaCommonViewModel.MediaRecommendations -> {
- val viewHolder =
- RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent)
- viewController.attachRecommendations(viewHolder)
- viewController.recommendationViewHolder?.recommendations?.layoutParams = lp
- MediaRecommendationsViewBinder.bind(
- viewHolder,
- commonViewModel.recsViewModel,
- viewController,
- falsingManager,
- backgroundDispatcher,
- mainDispatcher,
- )
- mediaContent.addView(viewHolder.recommendations, position)
- controllerById[commonViewModel.key] = viewController
- }
}
viewController.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded)
updateViewControllerToState(viewController, noAnimation = true)
@@ -695,21 +646,10 @@ constructor(
}
private fun onRemoved(commonViewModel: MediaCommonViewModel) {
- val id =
- when (commonViewModel) {
- is MediaCommonViewModel.MediaControl -> commonViewModel.instanceId.toString()
- is MediaCommonViewModel.MediaRecommendations -> commonViewModel.key
- }
+ val id = (commonViewModel as MediaCommonViewModel.MediaControl).instanceId.toString()
controllerById.remove(id)?.let {
- when (commonViewModel) {
- is MediaCommonViewModel.MediaControl -> {
- mediaCarouselScrollHandler.onPrePlayerRemoved(it.mediaViewHolder!!.player)
- mediaContent.removeView(it.mediaViewHolder!!.player)
- }
- is MediaCommonViewModel.MediaRecommendations -> {
- mediaContent.removeView(it.recommendationViewHolder!!.recommendations)
- }
- }
+ mediaCarouselScrollHandler.onPrePlayerRemoved(it.mediaViewHolder!!.player)
+ mediaContent.removeView(it.mediaViewHolder!!.player)
it.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
updatePageIndicator()
@@ -718,21 +658,10 @@ constructor(
}
private fun onMoved(commonViewModel: MediaCommonViewModel, from: Int, to: Int) {
- val id =
- when (commonViewModel) {
- is MediaCommonViewModel.MediaControl -> commonViewModel.instanceId.toString()
- is MediaCommonViewModel.MediaRecommendations -> commonViewModel.key
- }
+ val id = (commonViewModel as MediaCommonViewModel.MediaControl).instanceId.toString()
controllerById[id]?.let {
mediaContent.removeViewAt(from)
- when (commonViewModel) {
- is MediaCommonViewModel.MediaControl -> {
- mediaContent.addView(it.mediaViewHolder!!.player, to)
- }
- is MediaCommonViewModel.MediaRecommendations -> {
- mediaContent.addView(it.recommendationViewHolder!!.recommendations, to)
- }
- }
+ mediaContent.addView(it.mediaViewHolder!!.player, to)
}
updatePageIndicator()
mediaCarouselScrollHandler.onPlayersChanged()
@@ -746,11 +675,9 @@ constructor(
val viewIds =
viewModels
.map { mediaCommonViewModel ->
- when (mediaCommonViewModel) {
- is MediaCommonViewModel.MediaControl ->
- mediaCommonViewModel.instanceId.toString()
- is MediaCommonViewModel.MediaRecommendations -> mediaCommonViewModel.key
- }
+ (mediaCommonViewModel as MediaCommonViewModel.MediaControl)
+ .instanceId
+ .toString()
}
.toHashSet()
controllerById
@@ -758,7 +685,6 @@ constructor(
.forEach {
mediaCarouselScrollHandler.onPrePlayerRemoved(it.value.mediaViewHolder?.player)
mediaContent.removeView(it.value.mediaViewHolder?.player)
- mediaContent.removeView(it.value.recommendationViewHolder?.recommendations)
it.value.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
updatePageIndicator()
@@ -808,9 +734,6 @@ constructor(
mediaContent.removeAllViews()
for (mediaPlayer in MediaPlayerData.players()) {
mediaPlayer.mediaViewHolder?.let { mediaContent.addView(it.player) }
- ?: mediaPlayer.recommendationViewHolder?.let {
- mediaContent.addView(it.recommendations)
- }
}
mediaCarouselScrollHandler.onPlayersChanged()
mediaControlChipInteractor.updateMediaControlChipModelLegacy(
@@ -980,67 +903,6 @@ constructor(
return MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
}
- private fun addSmartspaceMediaRecommendations(
- key: String,
- data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- ) =
- traceSection("MediaCarouselController#addSmartspaceMediaRecommendations") {
- if (DEBUG) Log.d(TAG, "Updating smartspace target in carousel")
- MediaPlayerData.getMediaPlayer(key)?.let {
- Log.w(TAG, "Skip adding smartspace target in carousel")
- return
- }
-
- val existingSmartspaceMediaKey = MediaPlayerData.smartspaceMediaKey()
- existingSmartspaceMediaKey?.let {
- val removedPlayer =
- removePlayer(existingSmartspaceMediaKey, dismissMediaData = false)
- removedPlayer?.run {
- debugLogger.logPotentialMemoryLeak(existingSmartspaceMediaKey)
- onDestroy()
- }
- }
-
- val newRecs = mediaControlPanelFactory.get()
- newRecs.attachRecommendation(
- RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent)
- )
- newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
- val lp =
- LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- )
- newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
- newRecs.bindRecommendation(data)
- val curVisibleMediaKey =
- MediaPlayerData.visiblePlayerKeys()
- .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
- MediaPlayerData.addMediaRecommendation(
- key,
- data,
- newRecs,
- shouldPrioritize,
- systemClock,
- debugLogger,
- )
- updateViewControllerToState(newRecs.mediaViewController, noAnimation = true)
- reorderAllPlayers(curVisibleMediaKey)
- updatePageIndicator()
- mediaFrame.requiresRemeasuring = true
- // Check postcondition: mediaContent should have the same number of children as there
- // are elements in mediaPlayers.
- if (MediaPlayerData.players().size != mediaContent.childCount) {
- Log.e(
- TAG,
- "Size of players list and number of views in carousel are out of sync. " +
- "Players size is ${MediaPlayerData.players().size}. " +
- "View count is ${mediaContent.childCount}.",
- )
- }
- }
-
fun removePlayer(
key: String,
dismissMediaData: Boolean = true,
@@ -1057,7 +919,6 @@ constructor(
return removed?.apply {
mediaCarouselScrollHandler.onPrePlayerRemoved(removed.mediaViewHolder?.player)
mediaContent.removeView(removed.mediaViewHolder?.player)
- mediaContent.removeView(removed.recommendationViewHolder?.recommendations)
removed.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
mediaControlChipInteractor.updateMediaControlChipModelLegacy(
@@ -1095,31 +956,18 @@ constructor(
val mediaDataList = MediaPlayerData.mediaData()
// Do not loop through the original list of media data because the re-addition of media data
// is being executed in background thread.
- mediaDataList.forEach { (key, data, isSsMediaRec) ->
- if (isSsMediaRec) {
- val smartspaceMediaData = MediaPlayerData.smartspaceMediaData
+ mediaDataList.forEach { (key, data, _) ->
+ val isSsReactivated = MediaPlayerData.isSsReactivated(key)
+ if (recreateMedia) {
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
- smartspaceMediaData?.let {
- addSmartspaceMediaRecommendations(
- it.targetId,
- it,
- MediaPlayerData.shouldPrioritizeSs,
- )
- }
- onUiExecutionEnd.run()
- } else {
- val isSsReactivated = MediaPlayerData.isSsReactivated(key)
- if (recreateMedia) {
- removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
- }
- addOrUpdatePlayer(
- key = key,
- oldKey = null,
- data = data,
- isSsReactivated = isSsReactivated,
- onUiExecutionEnd = onUiExecutionEnd,
- )
}
+ addOrUpdatePlayer(
+ key = key,
+ oldKey = null,
+ data = data,
+ isSsReactivated = isSsReactivated,
+ onUiExecutionEnd = onUiExecutionEnd,
+ )
}
}
@@ -1129,12 +977,8 @@ constructor(
if (recreateMedia) {
mediaContent.removeAllViews()
commonViewModels.forEachIndexed { index, viewModel ->
- when (viewModel) {
- is MediaCommonViewModel.MediaControl ->
- controllerById[viewModel.instanceId.toString()]?.onDestroy()
- is MediaCommonViewModel.MediaRecommendations ->
- controllerById[viewModel.key]?.onDestroy()
- }
+ val mediaControlViewModel = (viewModel as MediaCommonViewModel.MediaControl)
+ controllerById[mediaControlViewModel.instanceId.toString()]?.onDestroy()
onAdded(viewModel, index, configChanged = true)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt
index 5d62c022efba..365389107648 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt
@@ -64,28 +64,6 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) {
{ "removing player $str1, by user $bool1" },
)
- fun logRecommendationLoaded(key: String, isActive: Boolean) =
- buffer.log(
- TAG,
- LogLevel.DEBUG,
- {
- str1 = key
- bool1 = isActive
- },
- { "add recommendation $str1, active $bool1" },
- )
-
- fun logRecommendationRemoved(key: String, immediately: Boolean) =
- buffer.log(
- TAG,
- LogLevel.DEBUG,
- {
- str1 = key
- bool1 = immediately
- },
- { "removing recommendation $str1, immediate=$bool1" },
- )
-
fun logCarouselHidden() = buffer.log(TAG, LogLevel.DEBUG, {}, { "hiding carousel" })
fun logCarouselVisible() = buffer.log(TAG, LogLevel.DEBUG, {}, { "showing carousel" })
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index a6bf5f43698b..006eb203a669 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -22,7 +22,6 @@ import static com.android.settingslib.flags.Flags.legacyLeAudioSharing;
import static com.android.systemui.Flags.communalHub;
import static com.android.systemui.Flags.mediaLockscreenLaunchAnimation;
import static com.android.systemui.media.controls.domain.pipeline.MediaActionsKt.getNotificationActions;
-import static com.android.systemui.media.controls.shared.model.SmartspaceMediaDataKt.NUM_REQUIRED_RECOMMENDATIONS;
import static com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.MEDIA_PLAYER_SCRIM_END_ALPHA;
import static com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.MEDIA_PLAYER_SCRIM_END_ALPHA_LEGACY;
import static com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel.MEDIA_PLAYER_SCRIM_START_ALPHA;
@@ -35,24 +34,17 @@ import android.app.ActivityOptions;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.WallpaperColors;
-import android.app.smartspace.SmartspaceAction;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -69,14 +61,12 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
-import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -105,7 +95,6 @@ import com.android.systemui.media.controls.shared.model.MediaAction;
import com.android.systemui.media.controls.shared.model.MediaButton;
import com.android.systemui.media.controls.shared.model.MediaData;
import com.android.systemui.media.controls.shared.model.MediaDeviceData;
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData;
import com.android.systemui.media.controls.ui.animation.AnimationBindHandler;
import com.android.systemui.media.controls.ui.animation.ColorSchemeTransition;
import com.android.systemui.media.controls.ui.animation.MediaColorSchemesKt;
@@ -113,7 +102,6 @@ import com.android.systemui.media.controls.ui.animation.MetadataAnimationHandler
import com.android.systemui.media.controls.ui.binder.SeekBarObserver;
import com.android.systemui.media.controls.ui.view.GutsViewHolder;
import com.android.systemui.media.controls.ui.view.MediaViewHolder;
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder;
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel;
import com.android.systemui.media.controls.util.MediaDataUtils;
import com.android.systemui.media.controls.util.MediaUiEventLogger;
@@ -143,14 +131,12 @@ import com.android.systemui.util.ColorUtilKt;
import com.android.systemui.util.animation.TransitionLayout;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.settings.GlobalSettings;
-import com.android.systemui.util.time.SystemClock;
import dagger.Lazy;
import kotlin.Triple;
import kotlin.Unit;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@@ -165,17 +151,6 @@ public class MediaControlPanel {
protected static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
- private static final String EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME = "com.google"
- + ".android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity";
- private static final String EXTRAS_SMARTSPACE_INTENT =
- "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
- private static final String KEY_SMARTSPACE_ARTIST_NAME = "artist_name";
- private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND";
-
- private static final float REC_MEDIA_COVER_SCALE_FACTOR = 1.25f;
- private static final float MEDIA_REC_SCRIM_START_ALPHA = 0.15f;
- private static final float MEDIA_REC_SCRIM_END_ALPHA = 1.0f;
-
private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS);
// Buttons to show in small player when using semantic actions
@@ -215,17 +190,14 @@ public class MediaControlPanel {
private Context mContext;
private MediaViewHolder mMediaViewHolder;
- private RecommendationViewHolder mRecommendationViewHolder;
private String mKey;
private MediaData mMediaData;
- private SmartspaceMediaData mRecommendationData;
private MediaViewController mMediaViewController;
private MediaSession.Token mToken;
private MediaController mController;
private Lazy<MediaDataManager> mMediaDataManagerLazy;
// Uid for the media app.
protected int mUid = Process.INVALID_UID;
- private int mSmartspaceMediaItemsCount;
private MediaCarouselController mMediaCarouselController;
private final MediaOutputDialogManager mMediaOutputDialogManager;
private final FalsingManager mFalsingManager;
@@ -241,7 +213,6 @@ public class MediaControlPanel {
private final NotificationLockscreenUserManager mLockscreenUserManager;
// Used for logging.
- private SystemClock mSystemClock;
private MediaUiEventLogger mLogger;
private InstanceId mInstanceId;
private String mPackageName;
@@ -310,7 +281,6 @@ public class MediaControlPanel {
MediaOutputDialogManager mediaOutputDialogManager,
MediaCarouselController mediaCarouselController,
FalsingManager falsingManager,
- SystemClock systemClock,
MediaUiEventLogger logger,
KeyguardStateController keyguardStateController,
ActivityIntentHelper activityIntentHelper,
@@ -330,7 +300,6 @@ public class MediaControlPanel {
mMediaOutputDialogManager = mediaOutputDialogManager;
mMediaCarouselController = mediaCarouselController;
mFalsingManager = falsingManager;
- mSystemClock = systemClock;
mLogger = logger;
mKeyguardStateController = keyguardStateController;
mActivityIntentHelper = activityIntentHelper;
@@ -373,16 +342,6 @@ public class MediaControlPanel {
}
/**
- * Get the recommendation view holder used to display Smartspace media recs.
- *
- * @return the recommendation view holder
- */
- @Nullable
- public RecommendationViewHolder getRecommendationViewHolder() {
- return mRecommendationViewHolder;
- }
-
- /**
* Get the view controller used to display media controls
*
* @return the media view controller
@@ -465,7 +424,7 @@ public class MediaControlPanel {
mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
mSeekBarViewModel.setScrubbingChangeListener(mScrubbingChangeListener);
mSeekBarViewModel.setEnabledChangeListener(mEnabledChangeListener);
- mMediaViewController.attach(player, MediaViewController.TYPE.PLAYER);
+ mMediaViewController.attach(player);
vh.getPlayer().setOnLongClickListener(v -> {
if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) return true;
@@ -522,26 +481,6 @@ public class MediaControlPanel {
return result;
}
- /** Attaches the recommendations to the recommendation view holder. */
- public void attachRecommendation(RecommendationViewHolder vh) {
- mRecommendationViewHolder = vh;
- TransitionLayout recommendations = vh.getRecommendations();
-
- mMediaViewController.attach(recommendations, MediaViewController.TYPE.RECOMMENDATION);
- mMediaViewController.configurationChangeListener = this::updateRecommendationsVisibility;
-
- mRecommendationViewHolder.getRecommendations().setOnLongClickListener(v -> {
- if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) return true;
- if (!mMediaViewController.isGutsVisible()) {
- openGuts();
- return true;
- } else {
- closeGuts();
- return true;
- }
- });
- }
-
/** Bind this player view based on the data given. */
public void bindPlayer(@NonNull MediaData data, String key) {
SceneContainerFlag.assertInLegacyMode();
@@ -868,24 +807,6 @@ public class MediaControlPanel {
mMediaViewHolder.getPlayer().setContentDescription(contentDescription);
}
- private void bindRecommendationContentDescription(SmartspaceMediaData data) {
- if (mRecommendationViewHolder == null) {
- return;
- }
-
- CharSequence contentDescription;
- if (mMediaViewController.isGutsVisible()) {
- contentDescription =
- mRecommendationViewHolder.getGutsViewHolder().getGutsText().getText();
- } else if (data != null) {
- contentDescription = mContext.getString(R.string.controls_media_smartspace_rec_header);
- } else {
- contentDescription = null;
- }
-
- mRecommendationViewHolder.getRecommendations().setContentDescription(contentDescription);
- }
-
private void bindArtworkAndColors(MediaData data, String key, boolean updateBackground) {
final int traceCookie = data.hashCode();
final String traceName = "MediaControlPanel#bindArtworkAndColors<" + key + ">";
@@ -993,62 +914,6 @@ public class MediaControlPanel {
});
}
- private void bindRecommendationArtwork(
- SmartspaceAction recommendation,
- String packageName,
- int itemIndex
- ) {
- final int traceCookie = recommendation.hashCode();
- final String traceName =
- "MediaControlPanel#bindRecommendationArtwork<" + packageName + ">";
- Trace.beginAsyncSection(traceName, traceCookie);
-
- // Capture width & height from views in foreground for artwork scaling in background
- int width = mContext.getResources().getDimensionPixelSize(R.dimen.qs_media_rec_album_width);
- int height = mContext.getResources().getDimensionPixelSize(
- R.dimen.qs_media_rec_album_height_expanded);
-
- mBackgroundExecutor.execute(() -> {
- // Album art
- ColorScheme mutableColorScheme = null;
- Drawable artwork;
- Icon artworkIcon = recommendation.getIcon();
- WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
- if (wallpaperColors != null) {
- mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
- artwork = addGradientToRecommendationAlbum(artworkIcon, mutableColorScheme, width,
- height);
- } else {
- artwork = new ColorDrawable(Color.TRANSPARENT);
- }
-
- mMainExecutor.execute(() -> {
- // Bind the artwork drawable to media cover.
- ImageView mediaCover =
- mRecommendationViewHolder.getMediaCoverItems().get(itemIndex);
- // Rescale media cover
- Matrix coverMatrix = new Matrix(mediaCover.getImageMatrix());
- coverMatrix.postScale(REC_MEDIA_COVER_SCALE_FACTOR, REC_MEDIA_COVER_SCALE_FACTOR,
- 0.5f * width, 0.5f * height);
- mediaCover.setImageMatrix(coverMatrix);
- mediaCover.setImageDrawable(artwork);
-
- // Set up the app icon.
- ImageView appIconView = mRecommendationViewHolder.getMediaAppIcons().get(itemIndex);
- appIconView.clearColorFilter();
- try {
- Drawable icon = mContext.getPackageManager()
- .getApplicationIcon(packageName);
- appIconView.setImageDrawable(icon);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find icon for package " + packageName, e);
- appIconView.setImageResource(R.drawable.ic_music_note);
- }
- Trace.endAsyncSection(traceName, traceCookie);
- });
- });
- }
-
// This method should be called from a background thread. WallpaperColors.fromBitmap takes a
// good amount of time. We do that work on the background executor to avoid stalling animations
// on the UI Thread.
@@ -1088,21 +953,6 @@ public class MediaControlPanel {
MEDIA_PLAYER_SCRIM_START_ALPHA_LEGACY, MEDIA_PLAYER_SCRIM_END_ALPHA_LEGACY);
}
- @VisibleForTesting
- protected LayerDrawable addGradientToRecommendationAlbum(Icon artworkIcon,
- ColorScheme mutableColorScheme, int width, int height) {
- // First try scaling rec card using bitmap drawable.
- // If returns null, set drawable bounds.
- Drawable albumArt = getScaledRecommendationCover(artworkIcon, width, height);
- if (albumArt == null) {
- albumArt = getScaledBackground(artworkIcon, width, height);
- }
- GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
- R.drawable.qs_media_rec_scrim).mutate();
- return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
- MEDIA_REC_SCRIM_START_ALPHA, MEDIA_REC_SCRIM_END_ALPHA);
- }
-
private LayerDrawable setupGradientColorOnDrawable(Drawable albumArt, GradientDrawable gradient,
ColorScheme mutableColorScheme, float startAlpha, float endAlpha) {
int startColor;
@@ -1465,258 +1315,6 @@ public class MediaControlPanel {
return controller;
}
- /** Bind this recommendation view based on the given data. */
- public void bindRecommendation(@NonNull SmartspaceMediaData data) {
- if (mRecommendationViewHolder == null) {
- return;
- }
-
- if (!data.isValid()) {
- Log.e(TAG, "Received an invalid recommendation list; returning");
- return;
- }
-
- if (Trace.isEnabled()) {
- Trace.traceBegin(Trace.TRACE_TAG_APP,
- "MediaControlPanel#bindRecommendation<" + data.getPackageName() + ">");
- }
-
- mRecommendationData = data;
- mPackageName = data.getPackageName();
- mInstanceId = data.getInstanceId();
-
- // Set up recommendation card's header.
- ApplicationInfo applicationInfo;
- try {
- applicationInfo = mContext.getPackageManager()
- .getApplicationInfo(data.getPackageName(), 0 /* flags */);
- mUid = applicationInfo.uid;
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Fail to get media recommendation's app info", e);
- Trace.endSection();
- return;
- }
-
- CharSequence appName = data.getAppName(mContext);
- if (appName == null) {
- Log.w(TAG, "Fail to get media recommendation's app name");
- Trace.endSection();
- return;
- }
-
- PackageManager packageManager = mContext.getPackageManager();
- // Set up media source app's logo.
- Drawable icon = packageManager.getApplicationIcon(applicationInfo);
- fetchAndUpdateRecommendationColors(icon);
-
- // Set up media rec card's tap action if applicable.
- TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
- setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
- /* interactedSubcardRank */ -1);
- bindRecommendationContentDescription(data);
-
- List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
- List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
- List<SmartspaceAction> recommendations = data.getValidRecommendations();
-
- boolean hasTitle = false;
- boolean hasSubtitle = false;
- int fittedRecsNum = getNumberOfFittedRecommendations();
- for (int itemIndex = 0; itemIndex < NUM_REQUIRED_RECOMMENDATIONS; itemIndex++) {
- SmartspaceAction recommendation = recommendations.get(itemIndex);
-
- // Set up media item cover.
- ImageView mediaCoverImageView = mediaCoverItems.get(itemIndex);
- bindRecommendationArtwork(recommendation, data.getPackageName(), itemIndex);
-
- // Set up the media item's click listener if applicable.
- ViewGroup mediaCoverContainer = mediaCoverContainers.get(itemIndex);
- setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation, itemIndex);
- // Bubble up the long-click event to the card.
- mediaCoverContainer.setOnLongClickListener(v -> {
- if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) return true;
- View parent = (View) v.getParent();
- if (parent != null) {
- parent.performLongClick();
- }
- return true;
- });
-
- // Set up the accessibility label for the media item.
- String artistName = recommendation.getExtras()
- .getString(KEY_SMARTSPACE_ARTIST_NAME, "");
- if (artistName.isEmpty()) {
- mediaCoverImageView.setContentDescription(
- mContext.getString(
- R.string.controls_media_smartspace_rec_item_no_artist_description,
- recommendation.getTitle(), appName));
- } else {
- mediaCoverImageView.setContentDescription(
- mContext.getString(
- R.string.controls_media_smartspace_rec_item_description,
- recommendation.getTitle(), artistName, appName));
- }
-
- // Set up title
- CharSequence title = recommendation.getTitle();
- hasTitle |= !TextUtils.isEmpty(title);
- TextView titleView = mRecommendationViewHolder.getMediaTitles().get(itemIndex);
- titleView.setText(title);
-
- // Set up subtitle
- // It would look awkward to show a subtitle if we don't have a title.
- boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
- CharSequence subtitle = shouldShowSubtitleText ? recommendation.getSubtitle() : "";
- hasSubtitle |= !TextUtils.isEmpty(subtitle);
- TextView subtitleView = mRecommendationViewHolder.getMediaSubtitles().get(itemIndex);
- subtitleView.setText(subtitle);
-
- // Set up progress bar
- SeekBar mediaProgressBar =
- mRecommendationViewHolder.getMediaProgressBars().get(itemIndex);
- TextView mediaSubtitle = mRecommendationViewHolder.getMediaSubtitles().get(itemIndex);
- // show progress bar if the recommended album is played.
- Double progress = MediaDataUtils.getDescriptionProgress(recommendation.getExtras());
- if (progress == null || progress <= 0.0) {
- mediaProgressBar.setVisibility(View.GONE);
- mediaSubtitle.setVisibility(View.VISIBLE);
- } else {
- mediaProgressBar.setProgress((int) (progress * 100));
- mediaProgressBar.setVisibility(View.VISIBLE);
- mediaSubtitle.setVisibility(View.GONE);
- }
- }
- mSmartspaceMediaItemsCount = NUM_REQUIRED_RECOMMENDATIONS;
-
- // If there's no subtitles and/or titles for any of the albums, hide those views.
- ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
- ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
- final boolean titlesVisible = hasTitle;
- final boolean subtitlesVisible = hasSubtitle;
- mRecommendationViewHolder.getMediaTitles().forEach((titleView) -> {
- setVisibleAndAlpha(expandedSet, titleView.getId(), titlesVisible);
- setVisibleAndAlpha(collapsedSet, titleView.getId(), titlesVisible);
- });
- mRecommendationViewHolder.getMediaSubtitles().forEach((subtitleView) -> {
- setVisibleAndAlpha(expandedSet, subtitleView.getId(), subtitlesVisible);
- setVisibleAndAlpha(collapsedSet, subtitleView.getId(), subtitlesVisible);
- });
-
- // Media covers visibility.
- setMediaCoversVisibility(fittedRecsNum);
-
- // Guts
- Runnable onDismissClickedRunnable = () -> {
- closeGuts();
- mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
- data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
-
- Intent dismissIntent = data.getDismissIntent();
- if (dismissIntent == null) {
- Log.w(TAG, "Cannot create dismiss action click action: "
- + "extras missing dismiss_intent.");
- return;
- }
-
- if (dismissIntent.getComponent() != null
- && dismissIntent.getComponent().getClassName()
- .equals(EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)) {
- // Dismiss the card Smartspace data through Smartspace trampoline activity.
- mContext.startActivity(dismissIntent);
- } else {
- mBroadcastSender.sendBroadcast(dismissIntent);
- }
- };
- bindGutsMenuCommon(
- /* isDismissible= */ true,
- appName.toString(),
- mRecommendationViewHolder.getGutsViewHolder(),
- onDismissClickedRunnable);
-
- mController = null;
- if (mMetadataAnimationHandler == null || !mMetadataAnimationHandler.isRunning()) {
- mMediaViewController.refreshState();
- }
- Trace.endSection();
- }
-
- private Unit updateRecommendationsVisibility() {
- int fittedRecsNum = getNumberOfFittedRecommendations();
- setMediaCoversVisibility(fittedRecsNum);
- return Unit.INSTANCE;
- }
-
- private void setMediaCoversVisibility(int fittedRecsNum) {
- ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
- ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
- List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
- // Hide media cover that cannot fit in the recommendation card.
- for (int itemIndex = 0; itemIndex < NUM_REQUIRED_RECOMMENDATIONS; itemIndex++) {
- setVisibleAndAlpha(expandedSet, mediaCoverContainers.get(itemIndex).getId(),
- itemIndex < fittedRecsNum);
- setVisibleAndAlpha(collapsedSet, mediaCoverContainers.get(itemIndex).getId(),
- itemIndex < fittedRecsNum);
- }
- }
-
- @VisibleForTesting
- protected int getNumberOfFittedRecommendations() {
- Resources res = mContext.getResources();
- Configuration config = res.getConfiguration();
- int defaultDpWidth = res.getInteger(R.integer.default_qs_media_rec_width_dp);
- int recCoverWidth = res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
- + res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2;
-
- // On landscape, media controls should take half of the screen width.
- int displayAvailableDpWidth = config.screenWidthDp;
- if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- displayAvailableDpWidth = displayAvailableDpWidth / 2;
- }
- int fittedNum;
- if (displayAvailableDpWidth > defaultDpWidth) {
- int recCoverDefaultWidth = res.getDimensionPixelSize(
- R.dimen.qs_media_rec_default_width);
- fittedNum = recCoverDefaultWidth / recCoverWidth;
- } else {
- int displayAvailableWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- displayAvailableDpWidth, res.getDisplayMetrics());
- fittedNum = displayAvailableWidth / recCoverWidth;
- }
- return Math.min(fittedNum, NUM_REQUIRED_RECOMMENDATIONS);
- }
-
- private void fetchAndUpdateRecommendationColors(Drawable appIcon) {
- mBackgroundExecutor.execute(() -> {
- ColorScheme colorScheme = new ColorScheme(
- WallpaperColors.fromDrawable(appIcon), /* darkTheme= */ true);
- mMainExecutor.execute(() -> setRecommendationColors(colorScheme));
- });
- }
-
- private void setRecommendationColors(ColorScheme colorScheme) {
- if (mRecommendationViewHolder == null) {
- return;
- }
-
- int backgroundColor = MediaColorSchemesKt.surfaceFromScheme(colorScheme);
- int textPrimaryColor = MediaColorSchemesKt.textPrimaryFromScheme(colorScheme);
- int textSecondaryColor = MediaColorSchemesKt.textSecondaryFromScheme(colorScheme);
-
- mRecommendationViewHolder.getCardTitle().setTextColor(textPrimaryColor);
-
- mRecommendationViewHolder.getRecommendations()
- .setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
- mRecommendationViewHolder.getMediaTitles().forEach(
- (title) -> title.setTextColor(textPrimaryColor));
- mRecommendationViewHolder.getMediaSubtitles().forEach(
- (subtitle) -> subtitle.setTextColor(textSecondaryColor));
- mRecommendationViewHolder.getMediaProgressBars().forEach(
- (progressBar) -> progressBar.setProgressTintList(
- ColorStateList.valueOf(textPrimaryColor)));
-
- mRecommendationViewHolder.getGutsViewHolder().setColors(colorScheme);
- }
-
private void bindGutsMenuCommon(
boolean isDismissible,
String appName,
@@ -1772,14 +1370,10 @@ public class MediaControlPanel {
public void closeGuts(boolean immediate) {
if (mMediaViewHolder != null) {
mMediaViewHolder.marquee(false, mMediaViewController.GUTS_ANIMATION_DURATION);
- } else if (mRecommendationViewHolder != null) {
- mRecommendationViewHolder.marquee(false, mMediaViewController.GUTS_ANIMATION_DURATION);
}
mMediaViewController.closeGuts(immediate);
if (mMediaViewHolder != null) {
bindPlayerContentDescription(mMediaData);
- } else if (mRecommendationViewHolder != null) {
- bindRecommendationContentDescription(mRecommendationData);
}
}
@@ -1790,14 +1384,10 @@ public class MediaControlPanel {
private void openGuts() {
if (mMediaViewHolder != null) {
mMediaViewHolder.marquee(true, mMediaViewController.GUTS_ANIMATION_DURATION);
- } else if (mRecommendationViewHolder != null) {
- mRecommendationViewHolder.marquee(true, mMediaViewController.GUTS_ANIMATION_DURATION);
}
mMediaViewController.openGuts();
if (mMediaViewHolder != null) {
bindPlayerContentDescription(mMediaData);
- } else if (mRecommendationViewHolder != null) {
- bindRecommendationContentDescription(mRecommendationData);
}
mLogger.logLongPressOpen(mUid, mPackageName, mInstanceId);
}
@@ -1822,29 +1412,6 @@ public class MediaControlPanel {
}
/**
- * Scale artwork to fill the background of media covers in recommendation card.
- */
- @UiThread
- private Drawable getScaledRecommendationCover(Icon artworkIcon, int width, int height) {
- if (width == 0 || height == 0) {
- return null;
- }
- if (artworkIcon != null) {
- Bitmap bitmap;
- if (artworkIcon.getType() == Icon.TYPE_BITMAP
- || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
- Bitmap artworkBitmap = artworkIcon.getBitmap();
- if (artworkBitmap != null) {
- bitmap = Bitmap.createScaledBitmap(artworkIcon.getBitmap(), width,
- height, false);
- return new BitmapDrawable(mContext.getResources(), bitmap);
- }
- }
- }
- return null;
- }
-
- /**
* Get the current media controller
*
* @return the controller
@@ -1896,64 +1463,5 @@ public class MediaControlPanel {
set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : notVisibleValue);
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
-
- private void setSmartspaceRecItemOnClickListener(
- @NonNull View view,
- @NonNull SmartspaceAction action,
- int interactedSubcardRank) {
- if (view == null || action == null || action.getIntent() == null
- || action.getIntent().getExtras() == null) {
- Log.e(TAG, "No tap action can be set up");
- return;
- }
-
- view.setOnClickListener(v -> {
- if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
-
- if (interactedSubcardRank == -1) {
- mLogger.logRecommendationCardTap(mPackageName, mInstanceId);
- } else {
- mLogger.logRecommendationItemTap(mPackageName, mInstanceId, interactedSubcardRank);
- }
-
- if (shouldSmartspaceRecItemOpenInForeground(action)) {
- // Request to unlock the device if the activity needs to be opened in foreground.
- mActivityStarter.postStartActivityDismissingKeyguard(
- action.getIntent(),
- 0 /* delay */,
- buildLaunchAnimatorController(
- mRecommendationViewHolder.getRecommendations()));
- } else {
- // Otherwise, open the activity in background directly.
- view.getContext().startActivity(action.getIntent());
- }
-
- // Automatically scroll to the active player once the media is loaded.
- mMediaCarouselController.setShouldScrollToKey(true);
- });
- }
-
- /** Returns if the Smartspace action will open the activity in foreground. */
- private boolean shouldSmartspaceRecItemOpenInForeground(SmartspaceAction action) {
- if (action == null || action.getIntent() == null
- || action.getIntent().getExtras() == null) {
- return false;
- }
-
- String intentString = action.getIntent().getExtras().getString(EXTRAS_SMARTSPACE_INTENT);
- if (intentString == null) {
- return false;
- }
-
- try {
- Intent wrapperIntent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME);
- return wrapperIntent.getBooleanExtra(KEY_SMARTSPACE_OPEN_IN_FOREGROUND, false);
- } catch (URISyntaxException e) {
- Log.wtf(TAG, "Failed to create intent from URI: " + intentString);
- e.printStackTrace();
- }
-
- return false;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index b687dce20b06..dba190022c8b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -38,7 +38,6 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.controls.ui.animation.ColorSchemeTransition
import com.android.systemui.media.controls.ui.animation.MetadataAnimationHandler
import com.android.systemui.media.controls.ui.binder.MediaControlViewBinder
-import com.android.systemui.media.controls.ui.binder.MediaRecommendationsViewBinder
import com.android.systemui.media.controls.ui.binder.SeekBarObserver
import com.android.systemui.media.controls.ui.controller.MediaCarouselController.Companion.calculateAlpha
import com.android.systemui.media.controls.ui.view.GutsViewHolder
@@ -48,7 +47,6 @@ import com.android.systemui.media.controls.ui.view.MediaViewHolder.Companion.hea
import com.android.systemui.media.controls.ui.view.MediaViewHolder.Companion.labelLargeTF
import com.android.systemui.media.controls.ui.view.MediaViewHolder.Companion.labelMediumTF
import com.android.systemui.media.controls.ui.view.MediaViewHolder.Companion.titleMediumTF
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.res.R
@@ -90,15 +88,6 @@ constructor(
private val globalSettings: GlobalSettings,
) {
- /**
- * Indicating that the media view controller is for a notification-based player, session-based
- * player, or recommendation
- */
- enum class TYPE {
- PLAYER,
- RECOMMENDATION,
- }
-
companion object {
@JvmField val GUTS_ANIMATION_DURATION = 234L
}
@@ -115,7 +104,6 @@ constructor(
private var animationDuration: Long = 0
private var animateNextStateChange: Boolean = false
private val measurement = MeasurementOutput(0, 0)
- private var type: TYPE = TYPE.PLAYER
/** A map containing all viewStates for all locations of this mediaState */
private val viewStates: MutableMap<CacheKey, TransitionViewState?> = mutableMapOf()
@@ -203,7 +191,6 @@ constructor(
private var isNextButtonAvailable = false
/** View holders for controller */
- var recommendationViewHolder: RecommendationViewHolder? = null
var mediaViewHolder: MediaViewHolder? = null
private lateinit var seekBarObserver: SeekBarObserver
@@ -417,13 +404,9 @@ constructor(
/** Set the height of UMO background constraints. */
private fun setBackgroundHeights(height: Int) {
- val backgroundIds =
- if (type == TYPE.PLAYER) {
- MediaViewHolder.backgroundIds
- } else {
- setOf(RecommendationViewHolder.backgroundId)
- }
- backgroundIds.forEach { id -> expandedLayout.getConstraint(id).layout.mHeight = height }
+ MediaViewHolder.backgroundIds.forEach { id ->
+ expandedLayout.getConstraint(id).layout.mHeight = height
+ }
}
/**
@@ -431,11 +414,7 @@ constructor(
* [TransitionViewState].
*/
private fun setGutsViewState(viewState: TransitionViewState) {
- val controlsIds =
- when (type) {
- TYPE.PLAYER -> MediaViewHolder.controlsIds
- TYPE.RECOMMENDATION -> RecommendationViewHolder.controlsIds
- }
+ val controlsIds = MediaViewHolder.controlsIds
val gutsIds = GutsViewHolder.ids
controlsIds.forEach { id ->
viewState.widgetStates.get(id)?.let { state ->
@@ -467,7 +446,6 @@ constructor(
squishedViewState.widgetStates.get(id)?.let { state -> state.height = squishedHeight }
}
- // media player
calculateWidgetGroupAlphaForSquishiness(
MediaViewHolder.expandedBottomActionIds,
squishedViewState.measureHeight.toFloat(),
@@ -480,20 +458,6 @@ constructor(
squishedViewState,
squishFraction,
)
- // recommendation card
- val titlesTop =
- calculateWidgetGroupAlphaForSquishiness(
- RecommendationViewHolder.mediaTitlesAndSubtitlesIds,
- squishedViewState.measureHeight.toFloat(),
- squishedViewState,
- squishFraction,
- )
- calculateWidgetGroupAlphaForSquishiness(
- RecommendationViewHolder.mediaContainersIds,
- titlesTop,
- squishedViewState,
- squishFraction,
- )
return squishedViewState
}
@@ -661,10 +625,10 @@ constructor(
* Attach a view to this controller. This may perform measurements if it's not available yet and
* should therefore be done carefully.
*/
- fun attach(transitionLayout: TransitionLayout, type: TYPE) =
+ fun attach(transitionLayout: TransitionLayout) =
traceSection("MediaViewController#attach") {
- loadLayoutForType(type)
- logger.logMediaLocation("attach $type", currentStartLocation, currentEndLocation)
+ loadLayoutConstraints()
+ logger.logMediaLocation("attach", currentStartLocation, currentEndLocation)
this.transitionLayout = transitionLayout
layoutController.attach(transitionLayout)
if (currentEndLocation == MediaHierarchyManager.LOCATION_UNKNOWN) {
@@ -691,7 +655,7 @@ constructor(
seekBarViewModel.setEnabledChangeListener(enabledChangeListener)
val mediaCard = mediaViewHolder.player
- attach(mediaViewHolder.player, TYPE.PLAYER)
+ attach(mediaViewHolder.player)
val turbulenceNoiseView = mediaViewHolder.turbulenceNoiseView
turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView)
@@ -813,15 +777,6 @@ constructor(
}
}
- fun attachRecommendations(recommendationViewHolder: RecommendationViewHolder) {
- if (!SceneContainerFlag.isEnabled) return
- this.recommendationViewHolder = recommendationViewHolder
-
- attach(recommendationViewHolder.recommendations, TYPE.RECOMMENDATION)
- recsConfigurationChangeListener =
- MediaRecommendationsViewBinder::updateRecommendationsVisibility
- }
-
fun bindSeekBar(onSeek: () -> Unit, onBindSeekBar: (SeekBarViewModel) -> Unit) {
if (!SceneContainerFlag.isEnabled) return
seekBarViewModel.logSeek = onSeek
@@ -1026,20 +981,10 @@ constructor(
return result
}
- private fun loadLayoutForType(type: TYPE) {
- this.type = type
-
- // These XML resources contain ConstraintSets that will apply to this player type's layout
- when (type) {
- TYPE.PLAYER -> {
- collapsedLayout.load(context, R.xml.media_session_collapsed)
- expandedLayout.load(context, R.xml.media_session_expanded)
- }
- TYPE.RECOMMENDATION -> {
- collapsedLayout.load(context, R.xml.media_recommendations_collapsed)
- expandedLayout.load(context, R.xml.media_recommendations_expanded)
- }
- }
+ private fun loadLayoutConstraints() {
+ // These XML resources contain ConstraintSets that will apply to this player's layout
+ collapsedLayout.load(context, R.xml.media_session_collapsed)
+ expandedLayout.load(context, R.xml.media_session_expanded)
readjustUIUpdateConstraints()
refreshState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
index f28edd638b10..2fc44ad3cce6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
@@ -42,8 +42,7 @@ class MediaViewModelCallback(
) {
oldItem.instanceId == newItem.instanceId
} else {
- oldItem is MediaCommonViewModel.MediaRecommendations &&
- newItem is MediaCommonViewModel.MediaRecommendations
+ false
}
}
@@ -56,11 +55,6 @@ class MediaViewModelCallback(
) {
oldItem.immediatelyUpdateUi == newItem.immediatelyUpdateUi &&
oldItem.updateTime == newItem.updateTime
- } else if (
- oldItem is MediaCommonViewModel.MediaRecommendations &&
- newItem is MediaCommonViewModel.MediaRecommendations
- ) {
- oldItem.key == newItem.key && oldItem.loadingEnabled == newItem.loadingEnabled
} else {
false
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/RecommendationViewHolder.kt
deleted file mode 100644
index 2d028d0213ff..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/RecommendationViewHolder.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.view
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.SeekBar
-import android.widget.TextView
-import com.android.internal.widget.CachingIconView
-import com.android.systemui.media.controls.ui.drawable.IlluminationDrawable
-import com.android.systemui.res.R
-import com.android.systemui.util.animation.TransitionLayout
-
-private const val TAG = "RecommendationViewHolder"
-
-/** ViewHolder for a Smartspace media recommendation. */
-class RecommendationViewHolder private constructor(itemView: View) {
-
- val recommendations = itemView as TransitionLayout
-
- // Recommendation screen
- val cardTitle: TextView = itemView.requireViewById(R.id.media_rec_title)
-
- val mediaCoverContainers =
- listOf<ViewGroup>(
- itemView.requireViewById(R.id.media_cover1_container),
- itemView.requireViewById(R.id.media_cover2_container),
- itemView.requireViewById(R.id.media_cover3_container)
- )
- val mediaAppIcons: List<CachingIconView> =
- mediaCoverContainers.map { it.requireViewById(R.id.media_rec_app_icon) }
- val mediaTitles: List<TextView> =
- mediaCoverContainers.map { it.requireViewById(R.id.media_title) }
- val mediaSubtitles: List<TextView> =
- mediaCoverContainers.map { it.requireViewById(R.id.media_subtitle) }
- val mediaProgressBars: List<SeekBar> =
- mediaCoverContainers.map {
- it.requireViewById<SeekBar?>(R.id.media_progress_bar).apply {
- // Media playback is in the direction of tape, not time, so it stays LTR
- layoutDirection = View.LAYOUT_DIRECTION_LTR
- }
- }
-
- val mediaCoverItems: List<ImageView> =
- mediaCoverContainers.map { it.requireViewById(R.id.media_cover) }
- val gutsViewHolder = GutsViewHolder(itemView)
-
- init {
- (recommendations.background as IlluminationDrawable).let { background ->
- mediaCoverContainers.forEach { background.registerLightSource(it) }
- background.registerLightSource(gutsViewHolder.cancel)
- background.registerLightSource(gutsViewHolder.dismiss)
- background.registerLightSource(gutsViewHolder.settings)
- }
- }
-
- fun marquee(start: Boolean, delay: Long) {
- gutsViewHolder.marquee(start, delay, TAG)
- }
-
- companion object {
- /**
- * Creates a RecommendationViewHolder.
- *
- * @param inflater LayoutInflater to use to inflate the layout.
- * @param parent Parent of inflated view.
- */
- @JvmStatic
- fun create(inflater: LayoutInflater, parent: ViewGroup): RecommendationViewHolder {
- val itemView =
- inflater.inflate(R.layout.media_recommendations, parent, false /* attachToRoot */)
- // Because this media view (a TransitionLayout) is used to measure and layout the views
- // in various states before being attached to its parent, we can't depend on the default
- // LAYOUT_DIRECTION_INHERIT to correctly resolve the ltr direction.
- itemView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
- return RecommendationViewHolder(itemView)
- }
-
- // Res Ids for the control components on the recommendation view.
- val controlsIds =
- setOf(
- R.id.media_rec_title,
- R.id.media_cover,
- R.id.media_cover1_container,
- R.id.media_cover2_container,
- R.id.media_cover3_container,
- R.id.media_title,
- R.id.media_subtitle,
- )
-
- val mediaTitlesAndSubtitlesIds =
- setOf(
- R.id.media_title,
- R.id.media_subtitle,
- )
-
- val mediaContainersIds =
- setOf(
- R.id.media_cover1_container,
- R.id.media_cover2_container,
- R.id.media_cover3_container
- )
-
- val backgroundId = R.id.sizing_view
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
index e5f1766fbb28..dfaee4434bcf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
@@ -49,7 +49,6 @@ constructor(
private val visualStabilityProvider: VisualStabilityProvider,
private val interactor: MediaCarouselInteractor,
private val controlInteractorFactory: MediaControlInteractorFactory,
- private val recommendationsViewModel: MediaRecommendationsViewModel,
private val logger: MediaUiEventLogger,
private val mediaLogger: MediaLogger,
) {
@@ -69,7 +68,7 @@ constructor(
when (commonModel) {
is MediaCommonModel.MediaControl -> add(toViewModel(commonModel))
is MediaCommonModel.MediaRecommendations ->
- add(toViewModel(commonModel))
+ return@forEach // TODO(b/382680767): remove
}
}
}
@@ -95,8 +94,6 @@ constructor(
private val mediaControlByInstanceId =
mutableMapOf<InstanceId, MediaCommonViewModel.MediaControl>()
- private var mediaRecs: MediaCommonViewModel.MediaRecommendations? = null
-
private var modelsPendingRemoval: MutableSet<MediaCommonModel> = mutableSetOf()
private var allowReorder = false
@@ -149,37 +146,6 @@ constructor(
)
}
- private fun toViewModel(
- commonModel: MediaCommonModel.MediaRecommendations
- ): MediaCommonViewModel.MediaRecommendations {
- return mediaRecs?.copy(
- key = commonModel.recsLoadingModel.key,
- loadingEnabled = interactor.isRecommendationActive(),
- )
- ?: MediaCommonViewModel.MediaRecommendations(
- key = commonModel.recsLoadingModel.key,
- loadingEnabled = interactor.isRecommendationActive(),
- recsViewModel = recommendationsViewModel,
- onAdded = { commonViewModel ->
- mediaLogger.logMediaRecommendationCardAdded(
- commonModel.recsLoadingModel.key
- )
- onMediaRecommendationAddedOrUpdated(
- commonViewModel as MediaCommonViewModel.MediaRecommendations
- )
- },
- onRemoved = { immediatelyRemove ->
- onMediaRecommendationRemoved(commonModel, immediatelyRemove)
- },
- onUpdated = { commonViewModel ->
- onMediaRecommendationAddedOrUpdated(
- commonViewModel as MediaCommonViewModel.MediaRecommendations
- )
- },
- )
- .also { mediaRecs = it }
- }
-
private fun onMediaControlAddedOrUpdated(
commonViewModel: MediaCommonViewModel,
commonModel: MediaCommonModel.MediaControl,
@@ -197,32 +163,6 @@ constructor(
}
}
- private fun onMediaRecommendationAddedOrUpdated(
- commonViewModel: MediaCommonViewModel.MediaRecommendations
- ) {
- if (!interactor.isRecommendationActive()) {
- commonViewModel.onRemoved(true)
- }
- }
-
- private fun onMediaRecommendationRemoved(
- commonModel: MediaCommonModel.MediaRecommendations,
- immediatelyRemove: Boolean,
- ) {
- mediaLogger.logMediaRecommendationCardRemoved(commonModel.recsLoadingModel.key)
- if (immediatelyRemove || isReorderingAllowed()) {
- interactor.dismissSmartspaceRecommendation(commonModel.recsLoadingModel.key, 0L)
- mediaRecs = null
- if (!immediatelyRemove) {
- // Although it wasn't requested, we were able to process the removal
- // immediately since reordering is allowed. So, notify hosts to update
- updateHostVisibility()
- }
- } else {
- modelsPendingRemoval.add(commonModel)
- }
- }
-
private fun isReorderingAllowed(): Boolean {
return visualStabilityProvider.isReorderingAllowed
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
index 52cb173b39cb..d493d57051f7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
@@ -35,13 +35,4 @@ sealed class MediaCommonViewModel {
val isMediaFromRec: Boolean = false,
val updateTime: Long = 0,
) : MediaCommonViewModel()
-
- data class MediaRecommendations(
- val key: String,
- val loadingEnabled: Boolean,
- val recsViewModel: MediaRecommendationsViewModel,
- override val onAdded: (MediaCommonViewModel) -> Unit,
- override val onRemoved: (Boolean) -> Unit,
- override val onUpdated: (MediaCommonViewModel) -> Unit,
- ) : MediaCommonViewModel()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
deleted file mode 100644
index 77add4035067..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.viewmodel
-
-import android.graphics.drawable.Drawable
-import android.graphics.drawable.Icon
-import com.android.systemui.animation.Expandable
-
-/** Models UI state for media recommendation item */
-data class MediaRecViewModel(
- val contentDescription: CharSequence,
- val title: CharSequence = "",
- val subtitle: CharSequence = "",
- /** track progress [0 - 100] for the recommendation album. */
- val progress: Int = 0,
- val albumIcon: Icon? = null,
- val appIcon: Drawable,
- val onClicked: ((Expandable, Int) -> Unit),
-)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
deleted file mode 100644
index 90313ddc736e..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.viewmodel
-
-import android.content.Context
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import android.os.Process
-import android.util.Log
-import com.android.internal.logging.InstanceId
-import com.android.systemui.animation.Expandable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
-import com.android.systemui.media.controls.shared.model.MediaRecModel
-import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
-import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
-import com.android.systemui.media.controls.ui.controller.MediaLocation
-import com.android.systemui.media.controls.ui.controller.MediaViewController.Companion.GUTS_ANIMATION_DURATION
-import com.android.systemui.media.controls.util.MediaDataUtils
-import com.android.systemui.media.controls.util.MediaUiEventLogger
-import com.android.systemui.res.R
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
-
-/** Models UI state and handles user input for media recommendations */
-@SysUISingleton
-class MediaRecommendationsViewModel
-@Inject
-constructor(
- @Application private val applicationContext: Context,
- @Background private val backgroundDispatcher: CoroutineDispatcher,
- private val interactor: MediaRecommendationsInteractor,
- private val logger: MediaUiEventLogger,
-) {
-
- val mediaRecsCard: Flow<MediaRecsCardViewModel?> =
- interactor.recommendations
- .map { recsCard -> toRecsViewModel(recsCard) }
- .distinctUntilChanged()
- .flowOn(backgroundDispatcher)
-
- @MediaLocation private var location = MediaHierarchyManager.LOCATION_UNKNOWN
-
- /**
- * Called whenever the recommendation has been expired or removed by the user. This method
- * removes the recommendation card entirely from the carousel.
- */
- private fun onMediaRecommendationsDismissed(
- key: String,
- uid: Int,
- packageName: String,
- dismissIntent: Intent?,
- instanceId: InstanceId?,
- ) {
- logger.logLongPressDismiss(uid, packageName, instanceId)
- interactor.removeMediaRecommendations(key, dismissIntent, GUTS_DISMISS_DELAY_MS_DURATION)
- }
-
- private fun onClicked(
- expandable: Expandable,
- intent: Intent?,
- packageName: String,
- instanceId: InstanceId?,
- index: Int,
- ) {
- if (intent == null || intent.extras == null) {
- Log.e(TAG, "No tap action can be set up")
- return
- }
-
- if (index == -1) {
- logger.logRecommendationCardTap(packageName, instanceId)
- } else {
- logger.logRecommendationItemTap(packageName, instanceId, index)
- }
-
- // set the package name of the player added by recommendation once the media is loaded.
- interactor.switchToMediaControl(packageName)
-
- interactor.startClickIntent(expandable, intent)
- }
-
- private suspend fun toRecsViewModel(model: MediaRecommendationsModel): MediaRecsCardViewModel? {
- if (!model.areRecommendationsValid) {
- Log.e(TAG, "Received an invalid recommendation list")
- return null
- }
- if (model.appName == null || model.uid == Process.INVALID_UID) {
- Log.w(TAG, "Fail to get media recommendation's app info")
- return null
- }
-
- val appIcon = getIconFromApp(model.packageName) ?: return null
-
- var areTitlesVisible = false
- var areSubtitlesVisible = false
- val mediaRecs =
- model.mediaRecs.map { mediaRecModel ->
- areTitlesVisible = areTitlesVisible || !mediaRecModel.title.isNullOrEmpty()
- areSubtitlesVisible = areSubtitlesVisible || !mediaRecModel.subtitle.isNullOrEmpty()
- val progress = MediaDataUtils.getDescriptionProgress(mediaRecModel.extras) ?: 0.0
- MediaRecViewModel(
- contentDescription =
- setUpMediaRecContentDescription(mediaRecModel, model.appName),
- title = mediaRecModel.title ?: "",
- subtitle = mediaRecModel.subtitle ?: "",
- progress = (progress * 100).toInt(),
- albumIcon = mediaRecModel.icon,
- appIcon = appIcon,
- onClicked = { expandable, index ->
- onClicked(
- expandable,
- mediaRecModel.intent,
- model.packageName,
- model.instanceId,
- index,
- )
- },
- )
- }
- // Subtitles should only be visible if titles are visible.
- areSubtitlesVisible = areTitlesVisible && areSubtitlesVisible
-
- return MediaRecsCardViewModel(
- contentDescription = { gutsVisible ->
- if (gutsVisible) {
- applicationContext.getString(
- R.string.controls_media_close_session,
- model.appName,
- )
- } else {
- applicationContext.getString(R.string.controls_media_smartspace_rec_header)
- }
- },
- onClicked = { expandable ->
- onClicked(
- expandable,
- model.dismissIntent,
- model.packageName,
- model.instanceId,
- index = -1,
- )
- },
- onLongClicked = {
- logger.logLongPressOpen(model.uid, model.packageName, model.instanceId)
- },
- mediaRecs = mediaRecs,
- areTitlesVisible = areTitlesVisible,
- areSubtitlesVisible = areSubtitlesVisible,
- gutsMenu = toGutsViewModel(model),
- onLocationChanged = { location = it },
- )
- }
-
- private fun toGutsViewModel(model: MediaRecommendationsModel): GutsViewModel {
- return GutsViewModel(
- gutsText =
- applicationContext.getString(R.string.controls_media_close_session, model.appName),
- onDismissClicked = {
- onMediaRecommendationsDismissed(
- model.key,
- model.uid,
- model.packageName,
- model.dismissIntent,
- model.instanceId,
- )
- },
- cancelTextBackground =
- applicationContext.getDrawable(R.drawable.qs_media_outline_button),
- onSettingsClicked = {
- logger.logLongPressSettings(model.uid, model.packageName, model.instanceId)
- interactor.startSettings()
- },
- )
- }
-
- private fun setUpMediaRecContentDescription(
- mediaRec: MediaRecModel,
- appName: CharSequence?,
- ): CharSequence {
- // Set up the accessibility label for the media item.
- val artistName = mediaRec.extras?.getString(KEY_SMARTSPACE_ARTIST_NAME, "")
- return if (artistName.isNullOrEmpty()) {
- applicationContext.getString(
- R.string.controls_media_smartspace_rec_item_no_artist_description,
- mediaRec.title,
- appName,
- )
- } else {
- applicationContext.getString(
- R.string.controls_media_smartspace_rec_item_description,
- mediaRec.title,
- artistName,
- appName,
- )
- }
- }
-
- private fun getIconFromApp(packageName: String): Drawable? {
- return try {
- applicationContext.packageManager.getApplicationIcon(packageName)
- } catch (e: PackageManager.NameNotFoundException) {
- Log.w(TAG, "Cannot find icon for package $packageName", e)
- null
- }
- }
-
- companion object {
- private const val TAG = "MediaRecommendationsViewModel"
- private const val KEY_SMARTSPACE_ARTIST_NAME = "artist_name"
- /**
- * Delay duration is based on [GUTS_ANIMATION_DURATION], it should have 100 ms increase in
- * order to let the animation end.
- */
- private const val GUTS_DISMISS_DELAY_MS_DURATION = 334L
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
deleted file mode 100644
index f1f7dc2195d5..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.viewmodel
-
-import com.android.systemui.animation.Expandable
-
-/** Models UI state for media recommendations card. */
-data class MediaRecsCardViewModel(
- val contentDescription: (Boolean) -> CharSequence,
- val onClicked: (Expandable) -> Unit,
- val onLongClicked: () -> Unit,
- val mediaRecs: List<MediaRecViewModel>,
- val areTitlesVisible: Boolean,
- val areSubtitlesVisible: Boolean,
- val gutsMenu: GutsViewModel,
- val onLocationChanged: (Int) -> Unit,
-)
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
index 1f2f571496bd..02dce406bbee 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
@@ -648,10 +648,6 @@ public class MediaSwitchingController
final MediaDevice connectedMediaDevice =
needToHandleMutingExpectedDevice ? null
: getCurrentConnectedMediaDevice();
-
- Set<String> selectedDevicesIds = getSelectedMediaDevice().stream()
- .map(MediaDevice::getId)
- .collect(Collectors.toSet());
if (oldMediaItems.isEmpty()) {
if (connectedMediaDevice == null) {
if (DEBUG) {
@@ -660,14 +656,12 @@ public class MediaSwitchingController
return categorizeMediaItemsLocked(
/* connectedMediaDevice */ null,
devices,
- selectedDevicesIds,
needToHandleMutingExpectedDevice);
} else {
// selected device exist
return categorizeMediaItemsLocked(
connectedMediaDevice,
devices,
- selectedDevicesIds,
/* needToHandleMutingExpectedDevice */ false);
}
}
@@ -701,18 +695,28 @@ public class MediaSwitchingController
devices.removeAll(targetMediaDevices);
targetMediaDevices.addAll(devices);
}
- List<MediaItem> finalMediaItems = new ArrayList<>();
+ List<MediaItem> finalMediaItems = targetMediaDevices.stream()
+ .map(MediaItem::createDeviceMediaItem)
+ .collect(Collectors.toList());
+
boolean shouldAddFirstSeenSelectedDevice =
com.android.media.flags.Flags.enableOutputSwitcherDeviceGrouping();
- for (MediaDevice targetMediaDevice : targetMediaDevices) {
- if (shouldAddFirstSeenSelectedDevice
- && selectedDevicesIds.contains(targetMediaDevice.getId())) {
- finalMediaItems.add(MediaItem.createDeviceMediaItem(
- targetMediaDevice, /* isFirstDeviceInGroup */ true));
- shouldAddFirstSeenSelectedDevice = false;
- } else {
- finalMediaItems.add(MediaItem.createDeviceMediaItem(
- targetMediaDevice, /* isFirstDeviceInGroup */ false));
+
+ if (shouldAddFirstSeenSelectedDevice) {
+ finalMediaItems.clear();
+ Set<String> selectedDevicesIds = getSelectedMediaDevice().stream()
+ .map(MediaDevice::getId)
+ .collect(Collectors.toSet());
+ for (MediaDevice targetMediaDevice : targetMediaDevices) {
+ if (shouldAddFirstSeenSelectedDevice
+ && selectedDevicesIds.contains(targetMediaDevice.getId())) {
+ finalMediaItems.add(MediaItem.createDeviceMediaItem(
+ targetMediaDevice, /* isFirstDeviceInGroup */ true));
+ shouldAddFirstSeenSelectedDevice = false;
+ } else {
+ finalMediaItems.add(MediaItem.createDeviceMediaItem(
+ targetMediaDevice, /* isFirstDeviceInGroup */ false));
+ }
}
}
dividerItems.forEach(finalMediaItems::add);
@@ -741,9 +745,11 @@ public class MediaSwitchingController
@GuardedBy("mMediaDevicesLock")
private List<MediaItem> categorizeMediaItemsLocked(MediaDevice connectedMediaDevice,
List<MediaDevice> devices,
- Set<String> selectedDevicesIds,
boolean needToHandleMutingExpectedDevice) {
List<MediaItem> finalMediaItems = new ArrayList<>();
+ Set<String> selectedDevicesIds = getSelectedMediaDevice().stream()
+ .map(MediaDevice::getId)
+ .collect(Collectors.toSet());
if (connectedMediaDevice != null) {
selectedDevicesIds.add(connectedMediaDevice.getId());
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
index 1e6954911889..c9fb8e877009 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
@@ -14,45 +14,690 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalMaterial3Api::class)
+
package com.android.systemui.media.remedia.ui.compose
+import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.tween
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.hoverable
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Slider
+import androidx.compose.material3.SliderColors
+import androidx.compose.material3.SliderDefaults.colors
+import androidx.compose.material3.SliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.center
+import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.CompositingStrategy
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.graphics.drawscope.clipRect
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastForEachIndexed
import com.android.compose.PlatformButton
import com.android.compose.PlatformIconButton
+import com.android.compose.PlatformOutlinedButton
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState
+import com.android.compose.animation.scene.transitions
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.common.ui.compose.load
+import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
import com.android.systemui.media.remedia.shared.model.MediaSessionState
+import com.android.systemui.media.remedia.ui.viewmodel.MediaCardGutsViewModel
+import com.android.systemui.media.remedia.ui.viewmodel.MediaCardViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaOutputSwitcherChipViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaPlayPauseActionViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaSecondaryActionViewModel
+import com.android.systemui.media.remedia.ui.viewmodel.MediaSeekBarViewModel
+import kotlin.math.max
+
+/** Renders the UI of a single media card. */
+@Composable
+private fun Card(
+ viewModel: MediaCardViewModel,
+ presentationStyle: MediaPresentationStyle,
+ modifier: Modifier = Modifier,
+) {
+ val stlState =
+ rememberMutableSceneTransitionLayoutState(
+ initialScene = presentationStyle.toScene(),
+ transitions = Media.Transitions,
+ )
+
+ // Each time the presentation style changes, animate to the corresponding scene.
+ LaunchedEffect(presentationStyle) {
+ stlState.setTargetScene(targetScene = presentationStyle.toScene(), animationScope = this)
+ }
+
+ Box(modifier) {
+ if (stlState.currentScene != Media.Scenes.Compact) {
+ CardBackground(imageLoader = viewModel.artLoader, modifier = Modifier.matchParentSize())
+ }
+
+ key(stlState) {
+ SceneTransitionLayout(state = stlState) {
+ scene(Media.Scenes.Default) {
+ CardForeground(viewModel = viewModel, threeRows = true, fillHeight = false)
+ }
+
+ scene(Media.Scenes.Compressed) {
+ CardForeground(viewModel = viewModel, threeRows = false, fillHeight = false)
+ }
+
+ scene(Media.Scenes.Compact) { CompactCardForeground(viewModel = viewModel) }
+ }
+ }
+ }
+}
+
+/**
+ * Renders the foreground of a card, including all UI content and the internal "guts".
+ *
+ * If [threeRows] is `true`, the layout will be organized as three horizontal rows; if `false`, two
+ * rows will be used, resulting in a more compact layout.
+ *
+ * If [fillHeight] is `true`, the card will grow vertically to fill all available space in its
+ * parent. If not, it'll only be as tall as needed to show its UI.
+ */
+@Composable
+private fun ContentScope.CardForeground(
+ viewModel: MediaCardViewModel,
+ threeRows: Boolean,
+ fillHeight: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ // Can't use a Crossfade composable because of the custom layout logic below. Animate the alpha
+ // of the guts (and, indirectly, of the content) from here.
+ val gutsAlphaAnimatable = remember { Animatable(0f) }
+ val isGutsVisible = viewModel.guts.isVisible
+ LaunchedEffect(isGutsVisible) { gutsAlphaAnimatable.animateTo(if (isGutsVisible) 1f else 0f) }
+
+ // Use a custom layout to measure the content even if the content is being hidden because the
+ // internal guts are showing. This is needed because only the content knows the size the of the
+ // card and the guts are set to be the same size of the content.
+ Layout(
+ content = {
+ CardForegroundContent(
+ viewModel = viewModel,
+ threeRows = threeRows,
+ fillHeight = fillHeight,
+ modifier =
+ Modifier.graphicsLayer {
+ compositingStrategy = CompositingStrategy.ModulateAlpha
+ alpha = 1f - gutsAlphaAnimatable.value
+ },
+ )
+
+ CardGuts(
+ viewModel = viewModel.guts,
+ modifier =
+ Modifier.graphicsLayer {
+ compositingStrategy = CompositingStrategy.ModulateAlpha
+ alpha = gutsAlphaAnimatable.value
+ },
+ )
+ },
+ modifier = modifier,
+ ) { measurables, constraints ->
+ check(measurables.size == 2)
+ val contentPlaceable = measurables[0].measure(constraints)
+ // Guts should always have the exact dimensions as the content, even if we don't show the
+ // content.
+ val gutsPlaceable =
+ measurables[1].measure(
+ Constraints.fixed(contentPlaceable.width, contentPlaceable.height)
+ )
+
+ layout(contentPlaceable.measuredWidth, contentPlaceable.measuredHeight) {
+ if (!viewModel.guts.isVisible || gutsAlphaAnimatable.isRunning) {
+ contentPlaceable.place(0, 0)
+ }
+ if (viewModel.guts.isVisible || gutsAlphaAnimatable.isRunning) {
+ gutsPlaceable.place(0, 0)
+ }
+ }
+ }
+}
+
+@Composable
+private fun ContentScope.CardForegroundContent(
+ viewModel: MediaCardViewModel,
+ threeRows: Boolean,
+ fillHeight: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ Column(
+ modifier =
+ modifier
+ .combinedClickable(
+ onClick = viewModel.onClick,
+ onLongClick = viewModel.onLongClick,
+ onClickLabel = viewModel.onClickLabel,
+ )
+ .padding(16.dp)
+ ) {
+ // Always add the first/top row, regardless of presentation style.
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ // Icon.
+ Icon(
+ icon = viewModel.icon,
+ tint = LocalAndroidColorScheme.current.primaryFixed,
+ modifier = Modifier.size(24.dp).clip(CircleShape),
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ viewModel.outputSwitcherChips.fastForEach { chip ->
+ OutputSwitcherChip(viewModel = chip, modifier = Modifier.padding(start = 8.dp))
+ }
+ }
+
+ // If the card is taller than necessary to show all the rows, this adds spacing
+ // between the top row and the rows below, anchoring the next rows to the bottom
+ // of the card.
+ if (fillHeight) {
+ Spacer(Modifier.weight(1f))
+ }
+
+ if (threeRows) {
+ // Three row presentation style.
+ //
+ // Second row.
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(top = 16.dp),
+ ) {
+ Metadata(
+ title = viewModel.title,
+ subtitle = viewModel.subtitle,
+ color = Color.White,
+ modifier = Modifier.weight(1f).padding(end = 8.dp),
+ )
+
+ AnimatedVisibility(visible = viewModel.playPauseAction.isVisible) {
+ PlayPauseAction(
+ viewModel = viewModel.playPauseAction,
+ buttonWidth = 48.dp,
+ buttonColor = LocalAndroidColorScheme.current.primaryFixed,
+ iconColor = LocalAndroidColorScheme.current.onPrimaryFixed,
+ buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 48.dp },
+ )
+ }
+ }
+
+ // Third row.
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(top = 24.dp),
+ ) {
+ Navigation(viewModel = viewModel.seekBar, isSeekBarVisible = true)
+ viewModel.additionalActions.fastForEachIndexed { index, action ->
+ SecondaryAction(
+ viewModel = action,
+ element = Media.Elements.additionalActionButton(index),
+ )
+ }
+ }
+ } else {
+ // Two row presentation style.
+ //
+ // Bottom row.
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(top = 36.dp),
+ ) {
+ Metadata(
+ title = viewModel.title,
+ subtitle = viewModel.subtitle,
+ color = Color.White,
+ modifier = Modifier.weight(1f).padding(end = 8.dp),
+ )
+
+ Navigation(
+ viewModel = viewModel.seekBar,
+ isSeekBarVisible = false,
+ modifier = Modifier.padding(end = 8.dp),
+ )
+
+ PlayPauseAction(
+ viewModel = viewModel.playPauseAction,
+ buttonWidth = 48.dp,
+ buttonColor = LocalAndroidColorScheme.current.primaryFixed,
+ iconColor = LocalAndroidColorScheme.current.onPrimaryFixed,
+ buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 48.dp },
+ )
+ }
+ }
+ }
+}
+
+/**
+ * Renders a simplified version of [CardForeground] that puts everything on a single row and doesn't
+ * support the guts.
+ */
+@Composable
+private fun ContentScope.CompactCardForeground(
+ viewModel: MediaCardViewModel,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier =
+ modifier
+ .clickable(onClick = viewModel.onClick, onClickLabel = viewModel.onClickLabel)
+ .background(MaterialTheme.colorScheme.surfaceContainer)
+ .padding(16.dp),
+ ) {
+ Icon(
+ icon = viewModel.icon,
+ tint = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.size(24.dp),
+ )
+
+ Metadata(
+ title = viewModel.title,
+ subtitle = viewModel.subtitle,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.weight(1f),
+ )
+
+ SecondaryAction(
+ viewModel = viewModel.outputSwitcherChipButton,
+ element = Media.Elements.OutputSwitcherButton,
+ iconColor = MaterialTheme.colorScheme.onSurface,
+ )
+
+ val nextAction = (viewModel.seekBar as? MediaSeekBarViewModel.Showing)?.next
+ if (nextAction != null) {
+ SecondaryAction(
+ viewModel = nextAction,
+ element = Media.Elements.NextButton,
+ iconColor = MaterialTheme.colorScheme.onSurface,
+ )
+ }
+
+ AnimatedVisibility(visible = viewModel.playPauseAction.isVisible) {
+ PlayPauseAction(
+ viewModel = viewModel.playPauseAction,
+ buttonWidth = 72.dp,
+ buttonColor = MaterialTheme.colorScheme.primaryContainer,
+ iconColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 24.dp },
+ )
+ }
+ }
+}
+
+/** Renders the background of a card, loading the artwork and showing an overlay on top of it. */
+@Composable
+private fun CardBackground(imageLoader: suspend () -> ImageBitmap, modifier: Modifier = Modifier) {
+ var image: ImageBitmap? by remember { mutableStateOf(null) }
+ LaunchedEffect(imageLoader) {
+ image = null
+ image = imageLoader()
+ }
+
+ val gradientBaseColor = MaterialTheme.colorScheme.onSurface
+ Box(
+ modifier =
+ modifier.drawWithContent {
+ // Draw the content of the box (loaded art or placeholder).
+ drawContent()
+
+ if (image != null) {
+ // Then draw the overlay.
+ drawRect(
+ brush =
+ Brush.radialGradient(
+ 0f to gradientBaseColor.copy(alpha = 0.65f),
+ 1f to gradientBaseColor.copy(alpha = 0.75f),
+ center = size.center,
+ radius = max(size.width, size.height) / 2,
+ )
+ )
+ }
+ }
+ ) {
+ image?.let { loadedImage ->
+ // Loaded art.
+ Image(
+ bitmap = loadedImage,
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier.matchParentSize(),
+ )
+ }
+ ?: run {
+ // Placeholder.
+ Box(Modifier.background(MaterialTheme.colorScheme.onSurface).matchParentSize())
+ }
+ }
+}
+
+/**
+ * Renders the navigation UI (seek bar and/or previous/next buttons).
+ *
+ * If [isSeekBarVisible] is `false`, the seek bar will not be included in the layout, even if it
+ * would otherwise be showing based on the view-model alone. This is meant for callers to decide
+ * whether they'd like to show the seek bar in addition to the prev/next buttons or just show the
+ * buttons.
+ */
+@Composable
+private fun ContentScope.Navigation(
+ viewModel: MediaSeekBarViewModel,
+ isSeekBarVisible: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ when (viewModel) {
+ is MediaSeekBarViewModel.Showing -> {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = modifier,
+ ) {
+ viewModel.previous?.let {
+ SecondaryAction(viewModel = it, element = Media.Elements.PrevButton)
+ }
+
+ val interactionSource = remember { MutableInteractionSource() }
+ val colors =
+ colors(
+ activeTrackColor = Color.White,
+ inactiveTrackColor = Color.White.copy(alpha = 0.3f),
+ thumbColor = Color.White,
+ )
+ if (isSeekBarVisible) {
+ // To allow the seek bar slider to fade in and out, it's tagged as an element.
+ Element(key = Media.Elements.SeekBarSlider, modifier = Modifier.weight(1f)) {
+ Slider(
+ interactionSource = interactionSource,
+ value = viewModel.progress,
+ onValueChange = { progress -> viewModel.onScrubChange(progress) },
+ onValueChangeFinished = { viewModel.onScrubFinished() },
+ colors = colors,
+ thumb = {
+ SeekBarThumb(interactionSource = interactionSource, colors = colors)
+ },
+ track = { sliderState ->
+ SeekBarTrack(
+ sliderState = sliderState,
+ isSquiggly = viewModel.isSquiggly,
+ colors = colors,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ },
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ }
+
+ viewModel.next?.let {
+ SecondaryAction(viewModel = it, element = Media.Elements.NextButton)
+ }
+ }
+ }
+
+ is MediaSeekBarViewModel.Hidden -> Unit
+ }
+}
+
+/** Renders the thumb of the seek bar. */
+@Composable
+private fun SeekBarThumb(
+ interactionSource: MutableInteractionSource,
+ colors: SliderColors,
+ modifier: Modifier = Modifier,
+) {
+ val interactions = remember { mutableStateListOf<Interaction>() }
+ LaunchedEffect(interactionSource) {
+ interactionSource.interactions.collect { interaction ->
+ when (interaction) {
+ is PressInteraction.Press -> interactions.add(interaction)
+ is PressInteraction.Release -> interactions.remove(interaction.press)
+ is PressInteraction.Cancel -> interactions.remove(interaction.press)
+ is DragInteraction.Start -> interactions.add(interaction)
+ is DragInteraction.Stop -> interactions.remove(interaction.start)
+ is DragInteraction.Cancel -> interactions.remove(interaction.start)
+ }
+ }
+ }
+
+ Spacer(
+ modifier
+ .size(width = 4.dp, height = 16.dp)
+ .hoverable(interactionSource = interactionSource)
+ .background(color = colors.thumbColor, shape = RoundedCornerShape(16.dp))
+ )
+}
+
+/**
+ * Renders the track of the seek bar.
+ *
+ * If [isSquiggly] is `true`, the part to the left of the thumb will animate a squiggly line that
+ * oscillates up and down. The [waveLength] and [amplitude] control the geometry of the squiggle and
+ * the [waveSpeedDpPerSec] controls the speed by which it seems to "move" horizontally.
+ */
+@Composable
+private fun SeekBarTrack(
+ sliderState: SliderState,
+ isSquiggly: Boolean,
+ colors: SliderColors,
+ modifier: Modifier = Modifier,
+ waveLength: Dp = 20.dp,
+ amplitude: Dp = 3.dp,
+ waveSpeedDpPerSec: Dp = 8.dp,
+) {
+ // Animating the amplitude allows the squiggle to gradually grow to its full height or shrink
+ // back to a flat line as needed.
+ val animatedAmplitude by
+ animateDpAsState(
+ targetValue = if (isSquiggly) amplitude else 0.dp,
+ label = "SeekBarTrack.amplitude",
+ )
+
+ // This animates the horizontal movement of the squiggle.
+ val animatedWaveOffset = remember { Animatable(0f) }
+
+ LaunchedEffect(isSquiggly) {
+ if (isSquiggly) {
+ animatedWaveOffset.snapTo(0f)
+ animatedWaveOffset.animateTo(
+ targetValue = 1f,
+ animationSpec =
+ infiniteRepeatable(
+ animation =
+ tween(
+ durationMillis = (1000 * (waveLength / waveSpeedDpPerSec)).toInt(),
+ easing = LinearEasing,
+ ),
+ repeatMode = RepeatMode.Restart,
+ ),
+ )
+ }
+ }
+
+ // Render the track.
+ Canvas(modifier = modifier) {
+ val thumbPositionPx = size.width * sliderState.value
+
+ // The squiggly part before the thumb.
+ if (thumbPositionPx > 0) {
+ val amplitudePx = amplitude.toPx()
+ val animatedAmplitudePx = animatedAmplitude.toPx()
+ val waveLengthPx = waveLength.toPx()
+
+ val path =
+ Path().apply {
+ val halfWaveLengthPx = waveLengthPx / 2
+ val halfWaveCount = (thumbPositionPx / halfWaveLengthPx).toInt()
+
+ repeat(halfWaveCount + 3) { index ->
+ // Draw a half wave (either a hill or a valley shape starting and ending on
+ // the horizontal center).
+ relativeQuadraticTo(
+ // The control point for the bezier curve is on top of the peak of the
+ // hill or the very center bottom of the valley shape.
+ dx1 = halfWaveLengthPx / 2,
+ dy1 = if (index % 2 == 0) -animatedAmplitudePx else animatedAmplitudePx,
+ // Advance horizontally, half a wave length at a time.
+ dx2 = halfWaveLengthPx,
+ dy2 = 0f,
+ )
+ }
+ }
+
+ // Now that the squiggle is rendered a bit past the thumb, clip off the part that passed
+ // the thumb. It's easier to clip the extra squiggle than to figure out the bezier curve
+ // for part of a hill/valley.
+ clipRect(
+ left = 0f,
+ top = -amplitudePx,
+ right = thumbPositionPx,
+ bottom = amplitudePx * 2,
+ ) {
+ translate(left = -waveLengthPx * animatedWaveOffset.value, top = 0f) {
+ // Actually render the squiggle.
+ drawPath(
+ path = path,
+ color = colors.activeTrackColor,
+ style = Stroke(width = 2.dp.toPx(), cap = StrokeCap.Round),
+ )
+ }
+ }
+ }
+
+ // The flat line after the thumb.
+ drawLine(
+ color = colors.inactiveTrackColor,
+ start = Offset(thumbPositionPx, 0f),
+ end = Offset(size.width, 0f),
+ strokeWidth = 2.dp.toPx(),
+ cap = StrokeCap.Round,
+ )
+ }
+}
+
+/** Renders the internal "guts" of a card. */
+@Composable
+private fun CardGuts(viewModel: MediaCardGutsViewModel, modifier: Modifier = Modifier) {
+ Box(
+ modifier =
+ modifier.pointerInput(Unit) { detectLongPressGesture { viewModel.onLongClick() } }
+ ) {
+ // Settings button.
+ Icon(
+ icon = checkNotNull(viewModel.settingsButton.icon),
+ modifier =
+ Modifier.align(Alignment.TopEnd).padding(top = 16.dp, end = 16.dp).clickable {
+ viewModel.settingsButton.onClick()
+ },
+ )
+
+ // Content.
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier =
+ Modifier.align(Alignment.BottomCenter)
+ .fillMaxWidth()
+ .padding(start = 16.dp, end = 32.dp, bottom = 40.dp),
+ ) {
+ Text(text = viewModel.text, color = Color.White)
+
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ PlatformButton(
+ onClick = viewModel.primaryAction.onClick,
+ colors = ButtonDefaults.buttonColors(containerColor = Color.White),
+ ) {
+ Text(
+ text = checkNotNull(viewModel.primaryAction.text),
+ color = LocalAndroidColorScheme.current.onPrimaryFixed,
+ )
+ }
+
+ viewModel.secondaryAction?.let { button ->
+ PlatformOutlinedButton(
+ onClick = button.onClick,
+ border = BorderStroke(width = 1.dp, color = Color.White),
+ ) {
+ Text(text = checkNotNull(button.text), color = Color.White)
+ }
+ }
+ }
+ }
+ }
+}
/** Renders the metadata labels of a track. */
@Composable
@@ -212,9 +857,43 @@ private fun SecondaryActionContent(
)
}
+/** Enumerates all supported media presentation styles. */
+enum class MediaPresentationStyle {
+ /** The "normal" 3-row carousel look. */
+ Default,
+ /** Similar to [Default] but not as tall (2-row carousel look). */
+ Compressed,
+ /** A special single-row treatment that fits nicely in quick settings. */
+ Compact,
+}
+
private object Media {
/**
+ * Scenes.
+ *
+ * The implementation uses a [SceneTransitionLayout] to smoothly animate transitions between
+ * different card layouts. Each card layout is identified as its own "scene" and the STL
+ * framework takes care of animating the layouts and their elements as the card morphs between
+ * scenes.
+ */
+ object Scenes {
+ /** The "normal" 3-row carousel look. */
+ val Default = SceneKey("default")
+ /** Similar to [Default] but not as tall (2-row carousel look). */
+ val Compressed = SceneKey("compressed")
+ /** A special single-row treatment that fits nicely in quick settings. */
+ val Compact = SceneKey("compact")
+ }
+
+ /** Definitions of how scene changes are transition-animated. */
+ val Transitions = transitions {
+ from(Scenes.Default, to = Scenes.Compact) {}
+ from(Scenes.Default, to = Scenes.Compressed) { fade(Elements.SeekBarSlider) }
+ from(Scenes.Compact, to = Scenes.Compressed) { fade(Elements.SeekBarSlider) }
+ }
+
+ /**
* Element keys.
*
* Composables that are wrapped in [ContentScope.Element] with one of these as their `key`
@@ -227,5 +906,21 @@ private object Media {
object Elements {
val PlayPauseButton = ElementKey("play_pause")
val Metadata = ElementKey("metadata")
+ val PrevButton = ElementKey("prev")
+ val NextButton = ElementKey("next")
+ val SeekBarSlider = ElementKey("seek_bar_slider")
+ val OutputSwitcherButton = ElementKey("output_switcher")
+
+ fun additionalActionButton(index: Int): ElementKey {
+ return ElementKey("additional_action_$index")
+ }
+ }
+}
+
+private fun MediaPresentationStyle.toScene(): SceneKey {
+ return when (this) {
+ MediaPresentationStyle.Default -> Media.Scenes.Default
+ MediaPresentationStyle.Compressed -> Media.Scenes.Compressed
+ MediaPresentationStyle.Compact -> Media.Scenes.Compact
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardGutsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardGutsViewModel.kt
new file mode 100644
index 000000000000..61e3bdced5f8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardGutsViewModel.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+data class MediaCardGutsViewModel(
+ val isVisible: Boolean,
+ val text: String,
+ val primaryAction: MediaGutsButtonViewModel,
+ val secondaryAction: MediaGutsButtonViewModel? = null,
+ val settingsButton: MediaGutsSettingsButtonViewModel,
+ val onLongClick: () -> Unit,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardViewModel.kt
new file mode 100644
index 000000000000..ecd6e6d094d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaCardViewModel.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import androidx.compose.runtime.Stable
+import androidx.compose.ui.graphics.ImageBitmap
+import com.android.systemui.common.shared.model.Icon
+
+/** Models UI state for a media card. */
+@Stable
+interface MediaCardViewModel {
+ /**
+ * Identifier. Must be unique across all media cards currently shown, to help the horizontal
+ * pager in the UI.
+ */
+ val key: Any
+
+ val icon: Icon
+
+ /**
+ * A callback to load the artwork for the media shown on this card. This callback will be
+ * invoked on the main thread, it's up to the implementation to move the loading off the main
+ * thread.
+ */
+ val artLoader: suspend () -> ImageBitmap
+
+ val title: String
+
+ val subtitle: String
+
+ val playPauseAction: MediaPlayPauseActionViewModel
+
+ val seekBar: MediaSeekBarViewModel
+
+ val additionalActions: List<MediaSecondaryActionViewModel>
+
+ val guts: MediaCardGutsViewModel
+
+ val outputSwitcherChips: List<MediaOutputSwitcherChipViewModel>
+
+ /** Simple icon-only version of the output switcher for use in compact UIs. */
+ val outputSwitcherChipButton: MediaSecondaryActionViewModel
+
+ val onClick: () -> Unit
+
+ /** Accessibility string for the click action of the card. */
+ val onClickLabel: String?
+
+ val onLongClick: () -> Unit
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsButtonViewModel.kt
index 9b7cd704aa2f..6ce0a014455f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsButtonViewModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.dagger.qualifiers
-import javax.inject.Qualifier
+package com.android.systemui.media.remedia.ui.viewmodel
-@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class Tracing
+data class MediaGutsButtonViewModel(val text: String, val onClick: () -> Unit)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsSettingsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsSettingsButtonViewModel.kt
new file mode 100644
index 000000000000..fabfe0e147c7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaGutsSettingsButtonViewModel.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import com.android.systemui.common.shared.model.Icon
+
+data class MediaGutsSettingsButtonViewModel(val icon: Icon, val onClick: () -> Unit)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSeekBarViewModel.kt
new file mode 100644
index 000000000000..f1ced6bf908d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSeekBarViewModel.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import androidx.annotation.FloatRange
+
+/** Models UI state for the seek bar. */
+sealed interface MediaSeekBarViewModel {
+
+ /** The seek bar should be showing. */
+ data class Showing(
+ /** The progress to show on the seek bar, between `0` and `1`. */
+ @FloatRange(from = 0.0, to = 1.0) val progress: Float,
+ /** The previous button; or `null` if it should be absent in the UI. */
+ val previous: MediaSecondaryActionViewModel?,
+ /** The next button; or `null` if it should be absent in the UI. */
+ val next: MediaSecondaryActionViewModel?,
+ /**
+ * Whether the portion of the seek bar track before the thumb should show the squiggle
+ * animation.
+ */
+ val isSquiggly: Boolean,
+ /**
+ * Whether the UI should show as "scrubbing" because the user is actively moving the thumb
+ * of the seek bar.
+ */
+ val isScrubbing: Boolean,
+ /**
+ * A callback to invoke while the user is "scrubbing" (e.g. actively moving the thumb of the
+ * seek bar). The position/progress of the actual track should not be changed during this
+ * time.
+ */
+ val onScrubChange: (progress: Float) -> Unit,
+ /**
+ * A callback to invoke once the user finishes "scrubbing" (e.g. stopped moving the thumb of
+ * the seek bar). The position/progress should be committed.
+ */
+ val onScrubFinished: () -> Unit,
+ ) : MediaSeekBarViewModel
+
+ /** The seek bar should be hidden. */
+ data object Hidden : MediaSeekBarViewModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt b/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt
index f29b15730986..aaed606f8fb2 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt
@@ -16,6 +16,8 @@
package com.android.systemui.model
+import com.android.systemui.shared.system.QuickStepContract.getSystemUiStateString
+
/**
* Represents a set of state changes. A bit can either be set to `true` or `false`.
*
@@ -43,13 +45,16 @@ class StateChange {
fun hasChanges() = flagsToSet != 0L || flagsToClear != 0L
- /** Applies all changed flags to [sysUiState]. */
+ /**
+ * Applies all changed flags to [sysUiState].
+ *
+ * Note this doesn't call [SysUiState.commitUpdate].
+ */
fun applyTo(sysUiState: SysUiState) {
iterateBits(flagsToSet or flagsToClear) { bit ->
val isBitSetInNewState = flagsToSet and bit != 0L
sysUiState.setFlag(bit, isBitSetInNewState)
}
- sysUiState.commitUpdate()
}
fun applyTo(sysUiState: Long): Long {
@@ -69,14 +74,25 @@ class StateChange {
}
}
- /** Clears all the flags changed in a [sysUiState] */
- fun clearAllChangedFlagsIn(sysUiState: SysUiState) {
+ /**
+ * Clears all the flags changed in a [sysUiState].
+ *
+ * Note this doesn't call [SysUiState.commitUpdate].
+ */
+ fun clearFrom(sysUiState: SysUiState) {
iterateBits(flagsToSet or flagsToClear) { bit -> sysUiState.setFlag(bit, false) }
- sysUiState.commitUpdate()
}
fun clear() {
flagsToSet = 0
flagsToClear = 0
}
+
+ override fun toString(): String {
+ return """StateChange(flagsToSet=${getSystemUiStateString(flagsToSet)}, flagsToClear=${
+ getSystemUiStateString(
+ flagsToClear
+ )
+ })"""
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt b/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt
index f95ae2501acb..2bdd9a88ad6c 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt
@@ -55,7 +55,7 @@ class SysUIStateDispatcher @Inject constructor() {
/** Called from each [SysUiState] to propagate new state changes. */
fun dispatchSysUIStateChange(sysUiFlags: Long, displayId: Int) {
- if (displayId != Display.DEFAULT_DISPLAY && !ShadeWindowGoesAround.isEnabled) return;
+ if (displayId != Display.DEFAULT_DISPLAY && !ShadeWindowGoesAround.isEnabled) return
listeners.forEach { listener ->
listener.onSystemUiStateChanged(sysUiFlags = sysUiFlags, displayId = displayId)
}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUIStateOverride.kt b/packages/SystemUI/src/com/android/systemui/model/SysUIStateOverride.kt
new file mode 100644
index 000000000000..89e06e226997
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUIStateOverride.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.model
+
+import android.view.Display
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/**
+ * This class is used to provide per-display overrides for only certain flags.
+ *
+ * While some of the [SystemUiStateFlags] are per display (e.g. shade expansion, dialog visible),
+ * some of them are device specific (e.g. whether it's awake or not). A [SysUIStateOverride] is
+ * created for each display that is not [Display.DEFAULT_DISPLAY], and if some flags are set on it,
+ * they will override whatever the default display state had in those.
+ */
+class SysUIStateOverride
+@AssistedInject
+constructor(
+ @Assisted override val displayId: Int,
+ private val sceneContainerPlugin: SceneContainerPlugin?,
+ dumpManager: DumpManager,
+ private val defaultDisplayState: SysUiState,
+ private val stateDispatcher: SysUIStateDispatcher,
+) : SysUiStateImpl(displayId, sceneContainerPlugin, dumpManager, stateDispatcher) {
+
+ private val override = StateChange()
+ private var lastSentFlags = defaultDisplayState.flags
+
+ private val defaultFlagsChangedCallback = { _: Long, otherDisplayId: Int ->
+ if (otherDisplayId == Display.DEFAULT_DISPLAY) {
+ commitUpdate()
+ }
+ }
+
+ override fun start() {
+ super.start()
+ stateDispatcher.registerListener(defaultFlagsChangedCallback)
+ }
+
+ override fun destroy() {
+ super.destroy()
+ stateDispatcher.unregisterListener(defaultFlagsChangedCallback)
+ }
+
+ override fun commitUpdate() {
+ if (flags != lastSentFlags) {
+ stateDispatcher.dispatchSysUIStateChange(flags, displayId)
+ lastSentFlags = flags
+ }
+ }
+
+ override val flags: Long
+ get() = override.applyTo(defaultDisplayState.flags)
+
+ override fun setFlag(@SystemUiStateFlags flag: Long, enabled: Boolean): SysUiState {
+ val toSet = flagWithOptionalOverrides(flag, enabled, displayId, sceneContainerPlugin)
+ override.setFlag(flag, toSet)
+ return this
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(displayId: Int): SysUIStateOverride
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
index 53105b2c0f6a..e99ee7ddb919 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
@@ -16,6 +16,7 @@
package com.android.systemui.model
import android.util.Log
+import android.view.Display
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.display.data.repository.PerDisplayInstanceProviderWithTeardown
@@ -74,6 +75,12 @@ interface SysUiState : Dumpable {
*/
fun destroy()
+ /** Initializes the state after construction. */
+ fun start()
+
+ /** The display ID this instances is associated with */
+ val displayId: Int
+
companion object {
const val DEBUG: Boolean = false
}
@@ -81,18 +88,19 @@ interface SysUiState : Dumpable {
private const val TAG = "SysUIState"
-class SysUiStateImpl
+open class SysUiStateImpl
@AssistedInject
constructor(
- @Assisted private val displayId: Int,
+ @Assisted override val displayId: Int,
private val sceneContainerPlugin: SceneContainerPlugin?,
private val dumpManager: DumpManager,
private val stateDispatcher: SysUIStateDispatcher,
) : SysUiState {
- private val debugName = "SysUiStateImpl-ForDisplay=$displayId"
+ private val debugName
+ get() = "SysUiStateImpl-ForDisplay=$displayId"
- init {
+ override fun start() {
dumpManager.registerNormalDumpable(debugName, this)
}
@@ -219,10 +227,19 @@ fun flagWithOptionalOverrides(
/** Creates and destroy instances of [SysUiState] */
@SysUISingleton
-class SysUIStateInstanceProvider @Inject constructor(private val factory: SysUiStateImpl.Factory) :
- PerDisplayInstanceProviderWithTeardown<SysUiState> {
+class SysUIStateInstanceProvider
+@Inject
+constructor(
+ private val factory: SysUiStateImpl.Factory,
+ private val overrideFactory: SysUIStateOverride.Factory,
+) : PerDisplayInstanceProviderWithTeardown<SysUiState> {
override fun createInstance(displayId: Int): SysUiState {
- return factory.create(displayId)
+ return if (displayId == Display.DEFAULT_DISPLAY) {
+ factory.create(displayId)
+ } else {
+ overrideFactory.create(displayId)
+ }
+ .apply { start() }
}
override fun destroyInstance(instance: SysUiState) {
diff --git a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
index a344a5cce6ba..3f804f768d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
@@ -42,7 +42,9 @@ object ModesUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, Flags.FLAG_MODES_UI)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, Flags.FLAG_MODES_UI)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index 5fa0095d2329..50d0a459da66 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -18,7 +18,6 @@ package com.android.systemui.navigationbar;
import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE_TAG;
import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen;
-import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
import static com.android.wm.shell.Flags.enableTaskbarOnPhones;
@@ -37,6 +36,7 @@ import android.view.Display;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManagerGlobal;
+import android.window.DesktopExperienceFlags;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -285,7 +285,7 @@ public class NavigationBarControllerImpl implements
@Override
public void onDisplayAddSystemDecorations(int displayId) {
- if (enableDisplayContentModeManagement()) {
+ if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
mHasNavBar.put(displayId, true);
}
Display display = mDisplayManager.getDisplay(displayId);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index c4d847f18269..efed260b4c99 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -44,7 +44,6 @@ import android.app.StatusBarManager.WindowVisibleState;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
-import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.InputMethodService.BackDispositionMode;
import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
import android.os.Handler;
@@ -503,9 +502,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
@Override
public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
@BackDispositionMode int backDisposition, boolean showImeSwitcher) {
- // Count imperceptible changes as visible so we transition taskbar out quickly.
- final boolean isImeVisible = mNavBarHelper.isImeVisible(vis)
- || (vis & InputMethodService.IME_VISIBLE_IMPERCEPTIBLE) != 0;
+ final boolean isImeVisible = mNavBarHelper.isImeVisible(vis);
final int flags = Utilities.updateNavbarFlagsFromIme(mNavbarFlags, backDisposition,
isImeVisible, showImeSwitcher);
if (flags == mNavbarFlags) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 7af538105cae..237ec7cfce7f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -1129,6 +1129,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mGestureBlockingActivityRunning.get(), mIsInPip, mDisplaySize,
mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
} else if (mAllowGesture || mLogGesture) {
+ boolean mLastFrameThresholdCrossed = mThresholdCrossed;
if (!mThresholdCrossed) {
mEndPoint.x = (int) ev.getX();
mEndPoint.y = (int) ev.getY();
@@ -1181,9 +1182,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
return;
} else if (dx > dy && dx > mTouchSlop) {
if (mAllowGesture) {
- if (mBackAnimation != null) {
- mBackAnimation.onThresholdCrossed();
- } else {
+ if (mBackAnimation == null) {
pilferPointers();
}
mThresholdCrossed = true;
@@ -1198,6 +1197,9 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
// forward touch
mEdgeBackPlugin.onMotionEvent(ev);
dispatchToBackAnimation(ev);
+ if (mBackAnimation != null && mThresholdCrossed && !mLastFrameThresholdCrossed) {
+ mBackAnimation.onThresholdCrossed();
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
index 694b525e7bc1..ea2bf6a44884 100644
--- a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
@@ -48,7 +48,7 @@ public class SystemProcessCondition extends Condition {
}
@Override
- protected int getStartStrategy() {
+ public int getStartStrategy() {
return START_EAGERLY;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 5e7e0c97a147..f1f5b267f9c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -63,6 +63,7 @@ import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.approachLayout
+import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInRoot
@@ -250,10 +251,23 @@ constructor(
private fun Content() {
PlatformTheme(isDarkTheme = true) {
ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) {
- if (viewModel.isQsVisibleAndAnyShadeExpanded) {
+ // TODO(b/389985793): Make sure that there is no coroutine work or recompositions
+ // happening when alwaysCompose is true but isQsVisibleAndAnyShadeExpanded is false.
+ if (alwaysCompose || viewModel.isQsVisibleAndAnyShadeExpanded) {
Box(
modifier =
- Modifier.graphicsLayer { alpha = viewModel.viewAlpha }
+ Modifier.thenIf(alwaysCompose) {
+ Modifier.layout { measurable, constraints ->
+ measurable.measure(constraints).run {
+ layout(width, height) {
+ if (viewModel.isQsVisibleAndAnyShadeExpanded) {
+ place(0, 0)
+ }
+ }
+ }
+ }
+ }
+ .graphicsLayer { alpha = viewModel.viewAlpha }
.thenIf(notificationScrimClippingParams.isEnabled) {
Modifier.notificationScrimClip {
notificationScrimClippingParams.params
@@ -331,12 +345,12 @@ constructor(
}
SceneTransitionLayout(state = sceneState, modifier = Modifier.fillMaxSize()) {
- scene(QuickSettings) {
+ scene(QuickSettings, alwaysCompose = alwaysCompose) {
LaunchedEffect(Unit) { viewModel.onQSOpen() }
Element(QuickSettings.rootElementKey, Modifier) { QuickSettingsElement() }
}
- scene(QuickQuickSettings) {
+ scene(QuickQuickSettings, alwaysCompose = alwaysCompose) {
LaunchedEffect(Unit) { viewModel.onQQSOpen() }
// Cannot pass the element modifier in because the top element has a `testTag`
// and this would overwrite it.
@@ -626,7 +640,20 @@ constructor(
) {
val Tiles =
@Composable {
- QuickQuickSettings(viewModel = viewModel.quickQuickSettingsViewModel)
+ QuickQuickSettings(
+ viewModel = viewModel.quickQuickSettingsViewModel,
+ listening = {
+ /*
+ * When always compose is false, this will always be true, and we'll be
+ * listening whenever this is composed.
+ * When always compose is true, we listen if we are visible and not
+ * fully expanded
+ */
+ !alwaysCompose ||
+ (viewModel.isQsVisibleAndAnyShadeExpanded &&
+ viewModel.expansionState.progress < 1f)
+ },
+ )
}
val Media =
@Composable {
@@ -716,7 +743,13 @@ constructor(
BrightnessSliderContainer(
viewModel = containerViewModel.brightnessSliderViewModel,
modifier =
- Modifier.systemGestureExclusionInShade().fillMaxWidth(),
+ Modifier.systemGestureExclusionInShade(
+ enabled = {
+ layoutState.transitionState is
+ TransitionState.Idle
+ }
+ )
+ .fillMaxWidth(),
)
}
val TileGrid =
@@ -726,6 +759,18 @@ constructor(
TileGrid(
viewModel = containerViewModel.tileGridViewModel,
modifier = Modifier.fillMaxWidth(),
+ listening = {
+ /*
+ * When always compose is false, this will always be true,
+ * and we'll be listening whenever this is composed.
+ * When always compose is true, we look a the second
+ * condition and we'll listen if QS is visible AND we are
+ * not fully collapsed.
+ */
+ !alwaysCompose ||
+ (viewModel.isQsVisibleAndAnyShadeExpanded &&
+ viewModel.expansionState.progress > 0f)
+ },
)
}
}
@@ -830,6 +875,7 @@ constructor(
println("qqsPositionOnScreen", rect)
}
println("QQS visible", qqsVisible.value)
+ println("Always composed", alwaysCompose)
if (::viewModel.isInitialized) {
printSection("View Model") { viewModel.dump(this@run, args) }
}
@@ -1177,3 +1223,6 @@ private fun interactionsConfig() =
// we are OK using this as our content is clipped and all corner radius are larger than this
surfaceCornerRadius = 28.dp,
)
+
+private inline val alwaysCompose
+ get() = Flags.alwaysComposeQsUiFragment()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
index 2eba36a25ae7..6865e0ee79f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
@@ -81,7 +81,9 @@ object QsDetailedView {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/** Returns a developer-readable string that describes the current requirement list. */
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
index 185ea93387a3..1fb884de620f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
@@ -27,7 +27,17 @@ import com.android.systemui.qs.pipeline.shared.TileSpec
/** A layout of tiles, indicating how they should be composed when showing in QS or in edit mode. */
interface GridLayout {
- @Composable fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier)
+
+ /**
+ * [listening] can be used to compose the grid but limit when tiles should be listening. It
+ * should be a function tracking a snapshot state.
+ */
+ @Composable
+ fun ContentScope.TileGrid(
+ tiles: List<TileViewModel>,
+ modifier: Modifier,
+ listening: () -> Boolean,
+ )
@Composable
fun EditTileGrid(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index a07120629d2b..865ae9a37d87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -32,7 +32,6 @@ import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
@@ -43,6 +42,7 @@ import androidx.compose.ui.res.integerResource
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ContentScope
import com.android.compose.modifiers.padding
+import com.android.systemui.common.ui.compose.PagerDots
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.development.ui.compose.BuildNumber
import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
@@ -65,17 +65,16 @@ constructor(
@PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout,
) : GridLayout by delegateGridLayout {
@Composable
- override fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
+ override fun ContentScope.TileGrid(
+ tiles: List<TileViewModel>,
+ modifier: Modifier,
+ listening: () -> Boolean,
+ ) {
val viewModel =
rememberViewModel(traceName = "PaginatedGridLayout-TileGrid") {
viewModelFactory.create()
}
- DisposableEffect(tiles) {
- val token = Any()
- tiles.forEach { it.startListening(token) }
- onDispose { tiles.forEach { it.stopListening(token) } }
- }
val columns = viewModel.columns
val rows = integerResource(R.integer.quick_settings_paginated_grid_num_rows)
@@ -122,7 +121,7 @@ constructor(
) {
val page = pages[it]
- with(delegateGridLayout) { TileGrid(tiles = page, modifier = Modifier) }
+ with(delegateGridLayout) { TileGrid(tiles = page, modifier = Modifier, listening) }
}
FooterBar(
buildNumberViewModelFactory = viewModel.buildNumberViewModelFactory,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
index cdc03bb9be35..d20b360756d7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -18,7 +18,6 @@ package com.android.systemui.qs.panels.ui.compose
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@@ -41,6 +40,7 @@ import com.android.systemui.res.R
fun ContentScope.QuickQuickSettings(
viewModel: QuickQuickSettingsViewModel,
modifier: Modifier = Modifier,
+ listening: () -> Boolean,
) {
val sizedTiles = viewModel.tileViewModels
@@ -51,11 +51,6 @@ fun ContentScope.QuickQuickSettings(
val spans by remember(sizedTiles) { derivedStateOf { sizedTiles.fastMap { it.width } } }
- DisposableEffect(tiles) {
- val token = Any()
- tiles.forEach { it.startListening(token) }
- onDispose { tiles.forEach { it.stopListening(token) } }
- }
val columns = viewModel.columns
Box(modifier = modifier) {
GridAnchor()
@@ -91,4 +86,6 @@ fun ContentScope.QuickQuickSettings(
}
}
}
+
+ TileListener(tiles, listening)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
index fd10f917106b..1858825f91ef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
@@ -22,9 +22,13 @@ import com.android.compose.animation.scene.ContentScope
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
@Composable
-fun ContentScope.TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) {
+fun ContentScope.TileGrid(
+ viewModel: TileGridViewModel,
+ modifier: Modifier = Modifier,
+ listening: () -> Boolean = { true },
+) {
val gridLayout = viewModel.gridLayout
val tiles = viewModel.tileViewModels
- with(gridLayout) { TileGrid(tiles, modifier) }
+ with(gridLayout) { TileGrid(tiles, modifier, listening) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileListener.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileListener.kt
new file mode 100644
index 000000000000..6fb8f1bb79a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileListener.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.snapshotFlow
+import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
+
+/**
+ * Use to have tiles start/stop listening when this is composed. Additionally, the listening state
+ * will be gated by [listeningEnabled].
+ */
+@Composable
+fun TileListener(tiles: List<TileViewModel>, listeningEnabled: () -> Boolean) {
+ LaunchedEffect(tiles) {
+ val token = Any()
+ try {
+ snapshotFlow { listeningEnabled() }
+ .collect { listening ->
+ tiles.forEach {
+ if (listening) {
+ it.startListening(token)
+ } else {
+ it.stopListening(token)
+ }
+ }
+ }
+ } finally {
+ tiles.forEach { it.stopListening(token) }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
index 85658bb71c8b..50012abc69d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
@@ -26,12 +26,14 @@ import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
+import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -39,6 +41,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
@@ -49,8 +52,16 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.BlendMode
+import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.CompositingStrategy
+import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
@@ -60,7 +71,7 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.semantics.toggleableState
-import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.modifiers.size
@@ -73,6 +84,9 @@ import com.android.systemui.common.ui.compose.load
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.SideIconHeight
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.SideIconWidth
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TILE_INITIAL_DELAY_MILLIS
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TILE_MARQUEE_ITERATIONS
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileLabelBlurWidth
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.longPressLabel
import com.android.systemui.qs.panels.ui.viewmodel.AccessibilityUiState
import com.android.systemui.qs.ui.compose.borderOnFocus
@@ -104,30 +118,31 @@ fun LargeTileContent(
val focusBorderColor = MaterialTheme.colorScheme.secondary
Box(
modifier =
- Modifier.size(CommonTileDefaults.ToggleTargetSize).thenIf(toggleClick != null) {
- Modifier.borderOnFocus(color = focusBorderColor, iconShape.topEnd)
- .clip(iconShape)
- .verticalSquish(squishiness)
- .drawBehind { drawRect(animatedBackgroundColor) }
- .combinedClickable(
- onClick = toggleClick!!,
- onLongClick = onLongClick,
- onLongClickLabel = longPressLabel,
- hapticFeedbackEnabled = !Flags.msdlFeedback(),
- )
- .thenIf(accessibilityUiState != null) {
- Modifier.semantics {
- accessibilityUiState as AccessibilityUiState
- contentDescription = accessibilityUiState.contentDescription
- stateDescription = accessibilityUiState.stateDescription
- accessibilityUiState.toggleableState?.let {
- toggleableState = it
+ Modifier.size(CommonTileDefaults.ToggleTargetSize)
+ .clip(iconShape)
+ .verticalSquish(squishiness)
+ .drawBehind { drawRect(animatedBackgroundColor) }
+ .thenIf(toggleClick != null) {
+ Modifier.borderOnFocus(color = focusBorderColor, iconShape.topEnd)
+ .combinedClickable(
+ onClick = toggleClick!!,
+ onLongClick = onLongClick,
+ onLongClickLabel = longPressLabel,
+ hapticFeedbackEnabled = !Flags.msdlFeedback(),
+ )
+ .thenIf(accessibilityUiState != null) {
+ Modifier.semantics {
+ accessibilityUiState as AccessibilityUiState
+ contentDescription = accessibilityUiState.contentDescription
+ stateDescription = accessibilityUiState.stateDescription
+ accessibilityUiState.toggleableState?.let {
+ toggleableState = it
+ }
+ role = Role.Switch
}
- role = Role.Switch
- }
- .sysuiResTag(TEST_TAG_TOGGLE)
- }
- }
+ .sysuiResTag(TEST_TAG_TOGGLE)
+ }
+ }
) {
SmallTileContent(
iconProvider = iconProvider,
@@ -167,18 +182,15 @@ fun LargeTileLabels(
val animatedSecondaryLabelColor by
animateColorAsState(colors.secondaryLabel, label = "QSTileSecondaryLabelColor")
Column(verticalArrangement = Arrangement.Center, modifier = modifier.fillMaxHeight()) {
- BasicText(
- label,
+ TileLabel(
+ text = label,
style = MaterialTheme.typography.labelLarge,
color = { animatedLabelColor },
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
)
if (!TextUtils.isEmpty(secondaryLabel)) {
- BasicText(
+ TileLabel(
secondaryLabel ?: "",
color = { animatedSecondaryLabelColor },
- maxLines = 1,
style = MaterialTheme.typography.bodyMedium,
modifier =
Modifier.thenIf(
@@ -194,9 +206,9 @@ fun LargeTileLabels(
@Composable
fun SmallTileContent(
- modifier: Modifier = Modifier,
iconProvider: Context.() -> Icon,
color: Color,
+ modifier: Modifier = Modifier,
size: () -> Dp = { CommonTileDefaults.IconSize },
animateToEnd: Boolean = false,
) {
@@ -212,31 +224,39 @@ fun SmallTileContent(
}
}
if (loadedDrawable is Animatable) {
+ // Skip initial animation, icons should animate only as the state change
+ // and not when first composed
+ var shouldSkipInitialAnimation by remember { mutableStateOf(true) }
+ LaunchedEffect(Unit) { shouldSkipInitialAnimation = animateToEnd }
+
val painter =
when (icon) {
is Icon.Resource -> {
val image = AnimatedImageVector.animatedVectorResource(id = icon.res)
key(icon) {
- if (animateToEnd) {
- rememberAnimatedVectorPainter(animatedImageVector = image, atEnd = true)
- } else {
- var atEnd by remember(icon.res) { mutableStateOf(false) }
- LaunchedEffect(key1 = icon.res) { atEnd = true }
- rememberAnimatedVectorPainter(
- animatedImageVector = image,
- atEnd = atEnd,
- )
- }
+ var atEnd by remember(icon) { mutableStateOf(shouldSkipInitialAnimation) }
+ LaunchedEffect(key1 = icon.res) { atEnd = true }
+
+ rememberAnimatedVectorPainter(animatedImageVector = image, atEnd = atEnd)
}
}
is Icon.Loaded -> {
- LaunchedEffect(loadedDrawable) {
+ val painter = rememberDrawablePainter(loadedDrawable)
+
+ // rememberDrawablePainter automatically starts the animation. Using
+ // SideEffect here to immediately stop it if needed
+ DisposableEffect(painter) {
if (loadedDrawable is AnimatedVectorDrawable) {
loadedDrawable.forceAnimationOnUI()
}
+ if (shouldSkipInitialAnimation) {
+ loadedDrawable.stop()
+ }
+ onDispose {}
}
- rememberDrawablePainter(loadedDrawable)
+
+ painter
}
}
@@ -251,6 +271,45 @@ fun SmallTileContent(
}
}
+@Composable
+private fun TileLabel(
+ text: String,
+ color: ColorProducer,
+ style: TextStyle,
+ modifier: Modifier = Modifier,
+) {
+ BasicText(
+ text = text,
+ color = color,
+ style = style,
+ maxLines = 1,
+ modifier =
+ modifier
+ .fillMaxWidth()
+ .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
+ .drawWithContent {
+ drawContent()
+ // Draw a blur over the end of the text
+ val edgeWidthPx = TileLabelBlurWidth.toPx()
+ drawRect(
+ topLeft = Offset(size.width - edgeWidthPx, 0f),
+ size = Size(edgeWidthPx, size.height),
+ brush =
+ Brush.horizontalGradient(
+ colors = listOf(Color.Transparent, Color.Black),
+ startX = size.width,
+ endX = size.width - edgeWidthPx,
+ ),
+ blendMode = BlendMode.DstIn,
+ )
+ }
+ .basicMarquee(
+ iterations = TILE_MARQUEE_ITERATIONS,
+ initialDelayMillis = TILE_INITIAL_DELAY_MILLIS,
+ ),
+ )
+}
+
object CommonTileDefaults {
val IconSize = 32.dp
val LargeTileIconSize = 28.dp
@@ -258,9 +317,13 @@ object CommonTileDefaults {
val SideIconHeight = 20.dp
val ToggleTargetSize = 56.dp
val TileHeight = 72.dp
- val TilePadding = 8.dp
+ val TileStartPadding = 8.dp
+ val TileEndPadding = 16.dp
val TileArrangementPadding = 6.dp
val InactiveCornerRadius = 50.dp
+ val TileLabelBlurWidth = 32.dp
+ const val TILE_MARQUEE_ITERATIONS = 1
+ const val TILE_INITIAL_DELAY_MILLIS = 2000
@Composable fun longPressLabel() = stringResource(id = R.string.accessibility_long_click_tile)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index 6e6c0b61d85b..69b967a68c3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -713,7 +713,7 @@ private fun AvailableTileGridCell(
// Displays the tile as an icon tile with the label underneath
Column(
horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = spacedBy(CommonTileDefaults.TilePadding, Alignment.Top),
+ verticalArrangement = spacedBy(CommonTileDefaults.TileStartPadding, Alignment.Top),
modifier =
modifier
.graphicsLayer { this.alpha = alpha }
@@ -813,7 +813,7 @@ fun EditTile(
placeable.place(startPadding.roundToInt(), 0)
}
}
- .tilePadding(),
+ .largeTilePadding(),
) {
// Icon
Box(Modifier.size(ToggleTargetSize)) {
@@ -847,7 +847,7 @@ private fun toAvailableTiles(
private fun MeasureScope.iconHorizontalCenter(containerSize: Int): Float {
return (containerSize - ToggleTargetSize.roundToPx()) / 2f -
- CommonTileDefaults.TilePadding.toPx()
+ CommonTileDefaults.TileStartPadding.toPx()
}
private fun Modifier.tileBackground(color: Color): Modifier {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 0503049382a8..6236ada46374 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -17,7 +17,6 @@
package com.android.systemui.qs.panels.ui.compose.infinitegrid
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@@ -34,6 +33,7 @@ import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.compose.PaginatableGridLayout
+import com.android.systemui.qs.panels.ui.compose.TileListener
import com.android.systemui.qs.panels.ui.compose.bounceableInfo
import com.android.systemui.qs.panels.ui.compose.rememberEditListState
import com.android.systemui.qs.panels.ui.viewmodel.BounceableTileViewModel
@@ -59,12 +59,11 @@ constructor(
) : PaginatableGridLayout {
@Composable
- override fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
- DisposableEffect(tiles) {
- val token = Any()
- tiles.forEach { it.startListening(token) }
- onDispose { tiles.forEach { it.stopListening(token) } }
- }
+ override fun ContentScope.TileGrid(
+ tiles: List<TileViewModel>,
+ modifier: Modifier,
+ listening: () -> Boolean,
+ ) {
val viewModel =
rememberViewModel(traceName = "InfiniteGridLayout.TileGrid") {
viewModelFactory.create()
@@ -116,6 +115,8 @@ constructor(
)
}
}
+
+ TileListener(tiles, listening)
}
@Composable
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index d73dc870756b..a56fabcc7dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -84,7 +84,9 @@ import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.flags.QsDetailedView
import com.android.systemui.qs.panels.ui.compose.BounceableInfo
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileEndPadding
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileHeight
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileStartPadding
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.longPressLabel
import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
@@ -270,7 +272,7 @@ fun TileContainer(
iconOnly = iconOnly,
)
.sysuiResTag(if (iconOnly) TEST_TAG_SMALL else TEST_TAG_LARGE)
- .tilePadding(),
+ .thenIf(!iconOnly) { Modifier.largeTilePadding() }, // Icon tiles are center aligned
content = content,
)
}
@@ -284,7 +286,7 @@ fun LargeStaticTile(uiState: TileUiState, modifier: Modifier = Modifier) {
.clip(TileDefaults.animateTileShapeAsState(state = uiState.state).value)
.background(colors.background)
.height(TileHeight)
- .tilePadding()
+ .largeTilePadding()
) {
LargeTileContent(
label = uiState.label,
@@ -311,8 +313,8 @@ fun tileHorizontalArrangement(): Arrangement.Horizontal {
return spacedBy(space = CommonTileDefaults.TileArrangementPadding, alignment = Alignment.Start)
}
-fun Modifier.tilePadding(): Modifier {
- return padding(CommonTileDefaults.TilePadding)
+fun Modifier.largeTilePadding(): Modifier {
+ return padding(start = TileStartPadding, end = TileEndPadding)
}
@Composable
@@ -356,10 +358,10 @@ private object TileDefaults {
val ActiveIconCornerRadius = 16.dp
val ActiveTileCornerRadius = 24.dp
- /** An active tile without dual target uses the active color as background */
+ /** An active icon tile uses the active color as background */
@Composable
@ReadOnlyComposable
- fun activeTileColors(): TileColors =
+ fun activeIconTileColors(): TileColors =
TileColors(
background = MaterialTheme.colorScheme.primary,
iconBackground = MaterialTheme.colorScheme.primary,
@@ -418,10 +420,10 @@ private object TileDefaults {
fun getColorForState(uiState: TileUiState, iconOnly: Boolean): TileColors {
return when (uiState.state) {
STATE_ACTIVE -> {
- if (uiState.handlesSecondaryClick && !iconOnly) {
+ if (!iconOnly) {
activeDualTargetTileColors()
} else {
- activeTileColors()
+ activeIconTileColors()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
index 7a6426c741a6..4be35f147c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
@@ -830,7 +830,8 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis
private void notifySystemUiStateFlags(@SystemUiStateFlags long flags, int displayId) {
if (SysUiState.DEBUG) {
Log.d(TAG_OPS, "Notifying sysui state change to launcher service: proxy="
- + mLauncherProxy + " flags=" + flags + " displayId=" + displayId);
+ + mLauncherProxy + " display=" + displayId + " flags="
+ + QuickStepContract.getSystemUiStateString(flags) + " displayId=" + displayId);
}
try {
if (mLauncherProxy != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 4753b9ac0457..7bb831baec20 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -687,7 +687,7 @@ constructor(
if (!isDeviceEntered) {
coroutineScope {
launch {
- deviceEntryHapticsInteractor.playSuccessHaptic
+ deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry
.sample(sceneInteractor.currentScene)
.collect { currentScene ->
if (Flags.msdlFeedback()) {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
index b0fb6193ee45..634323c1fe2e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
@@ -83,7 +83,9 @@ object SceneContainerFlag {
* testing.
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, DESCRIPTION)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, DESCRIPTION)
/** Returns a developer-readable string that describes the current requirement list. */
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 17fb50aa6890..24e7976011f4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -140,6 +140,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.brightness.data.repository.BrightnessMirrorShowingRepository;
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
import com.android.systemui.shade.data.repository.FlingInfo;
+import com.android.systemui.shade.data.repository.ShadeDisplaysRepository;
import com.android.systemui.shade.data.repository.ShadeRepository;
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor;
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
@@ -204,6 +205,7 @@ import dalvik.annotation.optimization.NeverCompile;
import com.google.android.msdl.data.model.MSDLToken;
import com.google.android.msdl.domain.MSDLPlayer;
+import dagger.Lazy;
import kotlin.Unit;
import kotlinx.coroutines.CoroutineDispatcher;
@@ -394,7 +396,7 @@ public final class NotificationPanelViewController implements
/** Whether the notifications are displayed full width (no margins on the side). */
private boolean mIsFullWidth;
private boolean mBlockingExpansionForCurrentTouch;
- // Following variables maintain state of events when input focus transfer may occur.
+ // Following variables maintain state of events when input focus transfer may occur.
private boolean mExpectingSynthesizedDown;
private boolean mLastEventSynthesizedDown;
@@ -456,6 +458,7 @@ public final class NotificationPanelViewController implements
@Deprecated // Use SysUIStateInteractor instead
private final SysUiState mSysUiState;
private final SysUIStateDisplaysInteractor mSysUIStateDisplaysInteractor;
+ private final Lazy<ShadeDisplaysRepository> mShadeDisplaysRepository;
private final NotificationShadeDepthController mDepthController;
private final NavigationBarController mNavigationBarController;
private final int mDisplayId;
@@ -637,7 +640,8 @@ public final class NotificationPanelViewController implements
KeyguardClockPositionAlgorithm keyguardClockPositionAlgorithm,
MSDLPlayer msdlPlayer,
BrightnessMirrorShowingRepository brightnessMirrorShowingRepository,
- BlurConfig blurConfig) {
+ BlurConfig blurConfig,
+ Lazy<ShadeDisplaysRepository> shadeDisplaysRepository) {
mBlurConfig = blurConfig;
SceneContainerFlag.assertInLegacyMode();
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@@ -745,6 +749,7 @@ public final class NotificationPanelViewController implements
mTapAgainViewController = tapAgainViewController;
mSysUiState = sysUiState;
mSysUIStateDisplaysInteractor = sysUIStateDisplaysInteractor;
+ mShadeDisplaysRepository = shadeDisplaysRepository;
mKeyguardBypassController = bypassController;
mUpdateMonitor = keyguardUpdateMonitor;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -2716,8 +2721,17 @@ public final class NotificationPanelViewController implements
}
private int getShadeDisplayId() {
- if (mView != null && mView.getDisplay() != null) return mView.getDisplay().getDisplayId();
- return Display.DEFAULT_DISPLAY;
+ if (ShadeWindowGoesAround.isEnabled()) {
+ var pendingDisplayId =
+ mShadeDisplaysRepository.get().getPendingDisplayId().getValue();
+ // Use the pendingDisplayId from the repository, *not* the Shade's context.
+ // This ensures correct UI state updates also if this method is called just *before*
+ // the Shade window moves to another display.
+ // The pendingDisplayId is guaranteed to be updated before this method is called.
+ return pendingDisplayId;
+ } else {
+ return Display.DEFAULT_DISPLAY;
+ }
}
private void setPerDisplaySysUIStateFlags() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 305444f7ab5e..fa17b4fad592 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -30,8 +30,6 @@ import android.graphics.Region;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Trace;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import android.view.IWindow;
@@ -75,7 +73,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
-import com.android.systemui.util.settings.SecureSettings;
import dagger.Lazy;
@@ -134,7 +131,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private final SysuiColorExtractor mColorExtractor;
private final NotificationShadeWindowModel mNotificationShadeWindowModel;
- private final SecureSettings mSecureSettings;
/**
* Layout params would be aggregated and dispatched all at once if this is > 0.
*
@@ -168,7 +164,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
Lazy<SelectedUserInteractor> userInteractor,
UserTracker userTracker,
NotificationShadeWindowModel notificationShadeWindowModel,
- SecureSettings secureSettings,
Lazy<CommunalInteractor> communalInteractor,
@ShadeDisplayAware LayoutParams shadeWindowLayoutParams) {
mContext = context;
@@ -186,7 +181,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
mBackgroundExecutor = backgroundExecutor;
mColorExtractor = colorExtractor;
mNotificationShadeWindowModel = notificationShadeWindowModel;
- mSecureSettings = secureSettings;
// prefix with {slow} to make sure this dumps at the END of the critical section.
dumpManager.registerCriticalDumpable("{slow}NotificationShadeWindowControllerImpl", this);
mAuthController = authController;
@@ -424,7 +418,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
(long) mLpChanged.preferredMaxDisplayRefreshRate);
}
- if (state.bouncerShowing && !isSecureWindowsDisabled()) {
+ if (state.bouncerShowing) {
mLpChanged.flags |= LayoutParams.FLAG_SECURE;
} else {
mLpChanged.flags &= ~LayoutParams.FLAG_SECURE;
@@ -437,13 +431,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
}
}
- private boolean isSecureWindowsDisabled() {
- return mSecureSettings.getIntForUser(
- Settings.Secure.DISABLE_SECURE_WINDOWS,
- 0,
- UserHandle.USER_CURRENT) == 1;
- }
-
private void adjustScreenOrientation(NotificationShadeWindowState state) {
if (state.bouncerShowing || state.isKeyguardShowingAndNotOccluded() || state.dozing) {
if (mKeyguardStateController.isKeyguardScreenRotationAllowed()) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index 96b224fbd4f3..cd224735cc62 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -36,6 +36,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.res.R
import com.android.systemui.scene.ui.view.WindowRootView
+import com.android.systemui.shade.data.repository.MutableShadeDisplaysRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepositoryImpl
import com.android.systemui.shade.display.ShadeDisplayPolicyModule
@@ -205,7 +206,18 @@ object ShadeDisplayAwareModule {
@SysUISingleton
@Provides
- fun provideShadePositionRepository(impl: ShadeDisplaysRepositoryImpl): ShadeDisplaysRepository {
+ fun provideShadePositionRepository(
+ impl: MutableShadeDisplaysRepository
+ ): ShadeDisplaysRepository {
+ ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
+ return impl
+ }
+
+ @SysUISingleton
+ @Provides
+ fun provideMutableShadePositionRepository(
+ impl: ShadeDisplaysRepositoryImpl
+ ): MutableShadeDisplaysRepository {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
return impl
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
index 79e63330e3a5..63b618f72921 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
@@ -50,7 +50,9 @@ object ShadeExpandsOnStatusBarLongPress {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
index 3513334f2a5c..e18ed83a1e8e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
@@ -22,16 +22,28 @@ import com.android.systemui.shade.display.ShadeDisplayPolicy
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-class FakeShadeDisplayRepository : ShadeDisplaysRepository {
+class FakeShadeDisplayRepository : MutableShadeDisplaysRepository {
private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
+ private val _pendingDisplayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
fun setDisplayId(displayId: Int) {
_displayId.value = displayId
}
+ fun setPendingDisplayId(displayId: Int) {
+ _pendingDisplayId.value = displayId
+ }
+
+ override fun onDisplayChangedSucceeded(displayId: Int) {
+ setDisplayId(displayId)
+ }
+
override val displayId: StateFlow<Int>
get() = _displayId
+ override val pendingDisplayId: StateFlow<Int>
+ get() = _pendingDisplayId
+
override val currentPolicy: ShadeDisplayPolicy
get() = FakeShadeDisplayPolicy
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
index 2a14ca44386d..7117a23bfb77 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
@@ -29,6 +29,7 @@ import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
@@ -40,10 +41,28 @@ import kotlinx.coroutines.flow.stateIn
/** Source of truth for the display currently holding the shade. */
interface ShadeDisplaysRepository {
- /** ID of the display which currently hosts the shade */
+ /** ID of the display which currently hosts the shade. */
val displayId: StateFlow<Int>
/** The current policy set. */
val currentPolicy: ShadeDisplayPolicy
+
+ /**
+ * Id of the display that should host the shade.
+ *
+ * If this differs from [displayId], it means there is a shade movement in progress. Classes
+ * that rely on the shade being already moved (and its context/resources updated) should rely on
+ * [displayId]. Classes that need to do work associated with the shade move, should listen at
+ * this.
+ */
+ val pendingDisplayId: StateFlow<Int>
+}
+
+/** Provides a way to set whether the display changed succeeded. */
+interface MutableShadeDisplaysRepository : ShadeDisplaysRepository {
+ /**
+ * To be called when the shade changed window, and its resources have been completely updated.
+ */
+ fun onDisplayChangedSucceeded(displayId: Int)
}
/**
@@ -63,7 +82,7 @@ constructor(
@ShadeOnDefaultDisplayWhenLocked private val shadeOnDefaultDisplayWhenLocked: Boolean,
keyguardRepository: KeyguardRepository,
displayRepository: DisplayRepository,
-) : ShadeDisplaysRepository {
+) : MutableShadeDisplaysRepository {
private val policy: StateFlow<ShadeDisplayPolicy> =
globalSettings
@@ -105,10 +124,16 @@ constructor(
override val currentPolicy: ShadeDisplayPolicy
get() = policy.value
- override val displayId: StateFlow<Int> =
+ override val pendingDisplayId: StateFlow<Int> =
keyguardAwareDisplayPolicy.stateIn(
bgScope,
SharingStarted.WhileSubscribed(),
Display.DEFAULT_DISPLAY,
)
+ private val _committedDisplayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
+ override val displayId: StateFlow<Int> = _committedDisplayId
+
+ override fun onDisplayChangedSucceeded(displayId: Int) {
+ _committedDisplayId.value = displayId
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 930b1cb1905c..0e0f58dc8d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -32,6 +32,7 @@ import com.android.systemui.shade.ShadeDisplayChangeLatencyTracker
import com.android.systemui.shade.ShadeTraceLogger.logMoveShadeWindowTo
import com.android.systemui.shade.ShadeTraceLogger.t
import com.android.systemui.shade.ShadeTraceLogger.traceReparenting
+import com.android.systemui.shade.data.repository.MutableShadeDisplaysRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.display.ShadeExpansionIntent
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
@@ -44,6 +45,7 @@ import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
@@ -55,7 +57,7 @@ import kotlinx.coroutines.withTimeoutOrNull
class ShadeDisplaysInteractor
@Inject
constructor(
- private val shadePositionRepository: ShadeDisplaysRepository,
+ private val shadePositionRepository: MutableShadeDisplaysRepository,
@ShadeDisplayAware private val shadeContext: WindowContext,
@ShadeDisplayAware private val configurationRepository: ConfigurationRepository,
@Background private val bgScope: CoroutineScope,
@@ -72,11 +74,14 @@ constructor(
private val hasActiveNotifications: Boolean
get() = activeNotificationsInteractor.areAnyNotificationsPresentValue
+ /** Current display id of the shade window. */
+ val displayId: StateFlow<Int> = shadePositionRepository.displayId
+
override fun start() {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
listenForWindowContextConfigChanges()
bgScope.launchTraced(TAG) {
- shadePositionRepository.displayId.collectLatest { displayId ->
+ shadePositionRepository.pendingDisplayId.collectLatest { displayId ->
moveShadeWindowTo(displayId)
}
}
@@ -119,6 +124,7 @@ constructor(
reparentToDisplayId(id = destinationId)
}
checkContextDisplayMatchesExpected(destinationId)
+ shadePositionRepository.onDisplayChangedSucceeded(destinationId)
}
}
} catch (e: IllegalStateException) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
index 016f50f471de..81824f69eddd 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
@@ -67,7 +67,9 @@ object ShadeWindowGoesAround {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index bfd512fa6a2d..ef0660fbcd1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -566,12 +566,11 @@ public final class KeyboardShortcutListSearch {
Arrays.asList(
Pair.create(KeyEvent.KEYCODE_TAB, KeyEvent.META_META_ON))),
/* Back: go back to previous state (back button) */
- /* Meta + Escape, Meta + backspace, Meta + left arrow */
+ /* Meta + Escape, Meta + left arrow */
new ShortcutKeyGroupMultiMappingInfo(
context.getString(R.string.group_system_go_back),
Arrays.asList(
Pair.create(KeyEvent.KEYCODE_ESCAPE, KeyEvent.META_META_ON),
- Pair.create(KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON),
Pair.create(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.META_META_ON))),
/* Take a full screenshot: Meta + S */
new ShortcutKeyGroupMultiMappingInfo(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index c9b96e9871ed..ec04edb0f810 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -76,6 +76,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController.StateList
import com.android.systemui.recents.LauncherProxyService;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
@@ -810,6 +811,10 @@ public class NotificationLockscreenUserManagerImpl implements
* lock time.
*/
private boolean shouldShowSensitiveContentRedactedView(NotificationEntry ent) {
+ if (android.app.Flags.redactionOnLockscreenMetrics()) {
+ return shouldShowSensitiveContentRedactedViewWithLog(ent);
+ }
+
if (!LockscreenOtpRedaction.isEnabled()) {
return false;
}
@@ -846,6 +851,71 @@ public class NotificationLockscreenUserManagerImpl implements
return true;
}
+ /*
+ * We show the sensitive content redaction view if
+ * 1. The feature is enabled
+ * 2. The notification has the `hasSensitiveContent` ranking variable set to true
+ * 3. The device is locked
+ * 4. The device is NOT connected to Wifi
+ * 5. The device has not connected to Wifi since receiving the notification
+ * 6. The notification arrived at least LOCK_TIME_FOR_SENSITIVE_REDACTION_MS after the last
+ * lock time.
+ *
+ * This version of the method logs a metric about the request.
+ */
+ private boolean shouldShowSensitiveContentRedactedViewWithLog(NotificationEntry ent) {
+ if (!LockscreenOtpRedaction.isEnabled()) {
+ return false;
+ }
+
+ if (ent.getRanking() == null || !ent.getRanking().hasSensitiveContent()) {
+ return false;
+ }
+
+ long notificationWhen = ent.getSbn().getNotification().getWhen();
+ long notificationTime = getEarliestNotificationTime(ent);
+ boolean locked = mLocked.get();
+ long lockTime = mLastLockTime.get();
+ boolean wifiConnected = mConnectedToWifi.get();
+ long wifiConnectionTime = mLastWifiConnectionTime.get();
+
+ boolean shouldRedact = true;
+ if (!locked) {
+ shouldRedact = false;
+ }
+
+ if (!mRedactOtpOnWifi.get()) {
+ if (wifiConnected) {
+ shouldRedact = false;
+ }
+
+ // If the device has connected to wifi since receiving the notification, do not redact
+ if (notificationTime < wifiConnectionTime) {
+ shouldRedact = false;
+ }
+ }
+
+ // If the lock screen was not already locked for at least mOtpRedactionRequiredLockTimeMs
+ // when this notification arrived, do not redact
+ long latestTimeForRedaction = lockTime + mOtpRedactionRequiredLockTimeMs.get();
+
+ if (notificationTime < latestTimeForRedaction) {
+ shouldRedact = false;
+ }
+
+ int whenAndEarliestDiff = clampLongToIntRange(notificationWhen - notificationTime);
+ int earliestAndLockDiff = clampLongToIntRange(lockTime - notificationTime);
+ int earliestAndWifiDiff = clampLongToIntRange(wifiConnectionTime - notificationTime);
+ SysUiStatsLog.write(SysUiStatsLog.OTP_NOTIFICATION_DISPLAYED, shouldRedact,
+ whenAndEarliestDiff, locked, earliestAndLockDiff, wifiConnected,
+ earliestAndWifiDiff);
+ return shouldRedact;
+ }
+
+ private int clampLongToIntRange(long toConvert) {
+ return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, toConvert));
+ }
+
// Get the earliest time the user might have seen this notification. This is either the
// notification's "when" time, or the notification entry creation time
private long getEarliestNotificationTime(NotificationEntry notif) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 84266e805773..bdfdb8191356 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -38,13 +38,13 @@ import com.android.systemui.Flags
import com.android.systemui.Flags.spatialModelAppPushback
import com.android.systemui.animation.ShadeInterpolation
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionListener
+import com.android.systemui.shared.Flags.ambientAod
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.DozeParameters
@@ -53,16 +53,15 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.WallpaperController
-import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor
import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
import com.android.wm.shell.appzoomout.AppZoomOut
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
import java.io.PrintWriter
import java.util.Optional
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.sign
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
/**
* Responsible for blurring the notification shade window, and applying a zoom effect to the
@@ -79,14 +78,12 @@ constructor(
private val keyguardInteractor: KeyguardInteractor,
private val choreographer: Choreographer,
private val wallpaperController: WallpaperController,
- private val wallpaperInteractor: WallpaperInteractor,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val dozeParameters: DozeParameters,
@ShadeDisplayAware private val context: Context,
private val splitShadeStateController: SplitShadeStateController,
private val windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
private val appZoomOutOptional: Optional<AppZoomOut>,
- @Application private val applicationScope: CoroutineScope,
dumpManager: DumpManager,
configurationController: ConfigurationController,
) : ShadeExpansionListener, Dumpable {
@@ -97,6 +94,7 @@ constructor(
private const val MIN_VELOCITY = -MAX_VELOCITY
private const val INTERACTION_BLUR_FRACTION = 0.8f
private const val ANIMATION_BLUR_FRACTION = 1f - INTERACTION_BLUR_FRACTION
+ private const val TRANSITION_THRESHOLD = 0.98f
private const val TAG = "DepthController"
}
@@ -115,8 +113,6 @@ constructor(
private var prevTimestamp: Long = -1
private var prevShadeDirection = 0
private var prevShadeVelocity = 0f
- private var prevDozeAmount: Float = 0f
- @VisibleForTesting var wallpaperSupportsAmbientMode: Boolean = false
// tracks whether app launch transition is in progress. This involves two independent factors
// that control blur, shade expansion and app launch animation from outside sysui.
// They can complete out of order, this flag will be reset by the animation that finishes later.
@@ -163,6 +159,9 @@ constructor(
/**
* When launching an app from the shade, the animations progress should affect how blurry the
* shade is, overriding the expansion amount.
+ *
+ * TODO(b/399617511): remove this once [Flags.notificationShadeBlur] is launched and the Shade
+ * closing is actually instantaneous.
*/
var blursDisabledForAppLaunch: Boolean = false
set(value) {
@@ -192,8 +191,12 @@ constructor(
return
}
- shadeAnimation.animateTo(0)
- shadeAnimation.finishIfRunning()
+ if (Flags.notificationShadeBlur()) {
+ shadeAnimation.skipTo(0)
+ } else {
+ shadeAnimation.animateTo(0)
+ shadeAnimation.finishIfRunning()
+ }
}
@Deprecated(
message =
@@ -226,15 +229,7 @@ constructor(
}
/** Blur radius of the wake-up animation on this frame. */
- private var wakeBlurRadius = 0f
- set(value) {
- if (field == value) return
- field = value
- scheduleUpdate()
- }
-
- /** Blur radius of the unlock animation on this frame. */
- private var unlockBlurRadius = 0f
+ private var wakeAndUnlockBlurRadius = 0f
set(value) {
if (field == value) return
field = value
@@ -261,16 +256,14 @@ constructor(
ShadeInterpolation.getNotificationScrimAlpha(qsPanelExpansion) * shadeExpansion
combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(qsExpandedRatio))
combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(transitionToFullShadeProgress))
- var shadeRadius = max(combinedBlur, max(wakeBlurRadius, unlockBlurRadius))
+ var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius)
if (areBlursDisabledForAppLaunch || blursDisabledForUnlock) {
shadeRadius = 0f
}
var blur = shadeRadius.toInt()
- // If the blur comes from waking up, we don't want to zoom out the background
- val zoomOut =
- if (shadeRadius != wakeBlurRadius) blurRadiusToZoomOut(blurRadius = shadeRadius) else 0f
+ val zoomOut = blurRadiusToZoomOut(blurRadius = shadeRadius)
// Make blur be 0 if it is necessary to stop blur effect.
if (scrimsVisible) {
if (!Flags.notificationShadeBlur()) {
@@ -355,14 +348,14 @@ constructor(
startDelay = keyguardStateController.keyguardFadingAwayDelay
interpolator = Interpolators.FAST_OUT_SLOW_IN
addUpdateListener { animation: ValueAnimator ->
- unlockBlurRadius =
+ wakeAndUnlockBlurRadius =
blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
}
addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
keyguardAnimator = null
- unlockBlurRadius = 0f
+ wakeAndUnlockBlurRadius = 0f
}
}
)
@@ -398,20 +391,15 @@ constructor(
}
override fun onDozeAmountChanged(linear: Float, eased: Float) {
- prevDozeAmount = eased
- updateWakeBlurRadius(prevDozeAmount)
+ wakeAndUnlockBlurRadius =
+ if (ambientAod()) {
+ 0f
+ } else {
+ blurUtils.blurRadiusOfRatio(eased)
+ }
}
}
- private fun updateWakeBlurRadius(ratio: Float) {
- wakeBlurRadius =
- if (!wallpaperSupportsAmbientMode) {
- 0f
- } else {
- blurUtils.blurRadiusOfRatio(ratio)
- }
- }
-
init {
dumpManager.registerCriticalDumpable(javaClass.name, this)
if (WAKE_UP_ANIMATION_ENABLED) {
@@ -433,12 +421,6 @@ constructor(
}
}
)
- applicationScope.launch {
- wallpaperInteractor.wallpaperSupportsAmbientMode.collect { supported ->
- wallpaperSupportsAmbientMode = supported
- updateWakeBlurRadius(prevDozeAmount)
- }
- }
initBlurListeners()
}
@@ -515,6 +497,22 @@ constructor(
scheduleUpdate()
}
+ fun onTransitionAnimationProgress(progress: Float) {
+ if (!Flags.notificationShadeBlur() || !Flags.moveTransitionAnimationLayer()) return
+ // Because the Shade takes a few frames to actually trigger the unblur after a transition
+ // has ended, we need to disable it manually, or the opening window itself will be blurred
+ // for a few frames due to relative ordering. We do this towards the end, so that the
+ // window is already covering the background and the unblur is not visible.
+ if (progress >= TRANSITION_THRESHOLD && shadeAnimation.radius > 0) {
+ blursDisabledForAppLaunch = true
+ }
+ }
+
+ fun onTransitionAnimationEnd() {
+ if (!Flags.notificationShadeBlur() || !Flags.moveTransitionAnimationLayer()) return
+ blursDisabledForAppLaunch = false
+ }
+
private fun updateShadeAnimationBlur(
expansion: Float,
tracking: Boolean,
@@ -613,8 +611,7 @@ constructor(
it.println("shouldApplyShadeBlur: ${shouldApplyShadeBlur()}")
it.println("shadeAnimation: ${shadeAnimation.radius}")
it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
- it.println("wakeBlur: $wakeBlurRadius")
- it.println("unlockBlur: $wakeBlurRadius")
+ it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
it.println("blursDisabledForAppLaunch: $blursDisabledForAppLaunch")
it.println("appLaunchTransitionIsInProgress: $appLaunchTransitionIsInProgress")
it.println("qsPanelExpansion: $qsPanelExpansion")
@@ -660,6 +657,20 @@ constructor(
springAnimation.addEndListener { _, _, _, _ -> pendingRadius = -1 }
}
+ /**
+ * Starts an animation to [newRadius], or updates the current one if already ongoing.
+ * IMPORTANT: do NOT use this method + [finishIfRunning] to instantaneously change the value
+ * of the animation. The change will NOT be instantaneous. Use [skipTo] instead.
+ *
+ * Explanation:
+ * 1. If idle, [SpringAnimation.animateToFinalPosition] requests a start to the animation.
+ * 2. On the first frame after an idle animation is requested to start, the animation simply
+ * acquires the starting value and does nothing else.
+ * 3. [SpringAnimation.skipToEnd] requests a fast-forward to the end value, but this happens
+ * during calculation of the next animation value. Because on the first frame no such
+ * calculation happens (point #2), there is one lagging frame where we still see the old
+ * value.
+ */
fun animateTo(newRadius: Int) {
if (pendingRadius == newRadius) {
return
@@ -668,6 +679,19 @@ constructor(
springAnimation.animateToFinalPosition(newRadius.toFloat())
}
+ /**
+ * Instantaneously set a new blur radius to this animation. Always use this instead of
+ * [animateTo] and [finishIfRunning] to make sure that the change takes effect in the next
+ * frame. See the doc for [animateTo] for an explanation.
+ */
+ fun skipTo(newRadius: Int) {
+ if (pendingRadius == newRadius) return
+ pendingRadius = newRadius
+ springAnimation.cancel()
+ springAnimation.setStartValue(newRadius.toFloat())
+ springAnimation.animateToFinalPosition(newRadius.toFloat())
+ }
+
fun finishIfRunning() {
if (springAnimation.isRunning) {
springAnimation.skipToEnd()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
index d8c3e2546a8f..a0de879845d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
@@ -56,7 +56,7 @@ constructor(
private val logger = Logger(logBuffer, "Notif".pad())
// [StatusBarChipLogTag] recommends a max tag length of 20, so [extraLogTag] should NOT be the
// top-level tag. It should instead be provided as the first string in each log message.
- private val extraLogTag = "SingleChipInteractor[key=$key]"
+ private val extraLogTag = "SingleNotifChipInteractor[key=$key][id=${hashCode()}]"
init {
if (startingModel.promotedContent == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
index 35e622ba8e44..9380dfe32bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
@@ -38,6 +38,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -45,6 +46,7 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
/** An interactor for the notification chips shown in the status bar. */
@SysUISingleton
@@ -147,28 +149,42 @@ constructor(
*/
val allNotificationChips: Flow<List<NotificationChipModel>> =
if (StatusBarNotifChips.isEnabled) {
- // For all our current interactors...
- // TODO(b/364653005): When a promoted notification is added or removed, each individual
- // interactor's [notificationChip] flow becomes un-collected then re-collected, which
- // can cause some flows to remove then add callbacks when they don't need to. Is there a
- // better structure for this? Maybe Channels or a StateFlow with a short timeout?
- promotedNotificationInteractors.flatMapLatest { interactors ->
- if (interactors.isNotEmpty()) {
- // Combine each interactor's [notificationChip] flow...
- val allNotificationChips: List<Flow<NotificationChipModel?>> =
- interactors.map { interactor -> interactor.notificationChip }
- combine(allNotificationChips) {
+ // For all our current interactors...
+ promotedNotificationInteractors.flatMapLatest { interactors ->
+ if (interactors.isNotEmpty()) {
+ // Combine each interactor's [notificationChip] flow...
+ val allNotificationChips: List<Flow<NotificationChipModel?>> =
+ interactors.map { interactor -> interactor.notificationChip }
+ combine(allNotificationChips) {
// ... and emit just the non-null & sorted chips
it.filterNotNull().sortedWith(chipComparator)
}
- .logSort()
- } else {
- flowOf(emptyList())
+ } else {
+ flowOf(emptyList())
+ }
}
+ } else {
+ flowOf(emptyList())
}
- } else {
- flowOf(emptyList())
- }
+ .distinctUntilChanged()
+ .logSort()
+ .stateIn(
+ backgroundScope,
+ SharingStarted.WhileSubscribed(
+ // When a promoted notification is added or removed, the `.flatMapLatest` above
+ // will stop collection and then re-start collection on each individual
+ // interactor's flow. (It will happen even for a chip that didn't change.) We
+ // don't want the individual interactor flows to stop then re-start because they
+ // may be maintaining values that would get thrown away when collection stops
+ // (like an app's last visible time).
+ // stopTimeoutMillis ensures we maintain those values even during the brief
+ // moment (1-2ms) when `.flatMapLatest` causes collect to stop then immediately
+ // restart.
+ // Note: Channels could also work to solve this.
+ stopTimeoutMillis = 1000
+ ),
+ initialValue = emptyList(),
+ )
/** Emits the notifications that should actually be *shown* as chips in the status bar. */
val shownNotificationChips: Flow<List<NotificationChipModel>> =
@@ -199,14 +215,14 @@ constructor(
}
private fun Flow<List<NotificationChipModel>>.logSort(): Flow<List<NotificationChipModel>> {
- return this.distinctUntilChanged().onEach { chips ->
+ return this.onEach { chips ->
val logString =
chips.joinToString {
"{key=${it.key}. " +
"lastVisibleAppTime=${it.lastAppVisibleTime}. " +
"creationTime=${it.creationTime}}"
}
- logger.d({ "Sorted chips: $str1" }) { str1 = logString }
+ logger.d({ "Sorted notif chips: $str1" }) { str1 = logString }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
index 947e93c8a432..6431f303089f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
@@ -50,7 +50,9 @@ object StatusBarNotifChips {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
index 5242feac898b..ac55bf2bee1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
@@ -27,11 +27,13 @@ import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.text.TextMeasurer
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.constrain
import androidx.compose.ui.unit.dp
@@ -45,6 +47,7 @@ import kotlin.math.min
@Composable
fun ChipContent(viewModel: OngoingActivityChipModel.Active, modifier: Modifier = Modifier) {
val context = LocalContext.current
+ val density = LocalDensity.current
val isTextOnly = viewModel.icon == null
val hasEmbeddedIcon =
viewModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView ||
@@ -86,7 +89,7 @@ fun ChipContent(viewModel: OngoingActivityChipModel.Active, modifier: Modifier =
startPadding = startPadding,
endPadding = endPadding,
)
- .neverDecreaseWidth(),
+ .neverDecreaseWidth(density),
)
}
@@ -97,7 +100,7 @@ fun ChipContent(viewModel: OngoingActivityChipModel.Active, modifier: Modifier =
style = textStyle,
color = textColor,
softWrap = false,
- modifier = modifier.neverDecreaseWidth(),
+ modifier = modifier.neverDecreaseWidth(density),
)
}
@@ -150,23 +153,31 @@ fun ChipContent(viewModel: OngoingActivityChipModel.Active, modifier: Modifier =
}
/** A modifier that ensures the width of the content only increases and never decreases. */
-private fun Modifier.neverDecreaseWidth(): Modifier {
- return this.then(NeverDecreaseWidthElement)
+private fun Modifier.neverDecreaseWidth(density: Density): Modifier {
+ return this.then(NeverDecreaseWidthElement(density))
}
-private data object NeverDecreaseWidthElement : ModifierNodeElement<NeverDecreaseWidthNode>() {
+private data class NeverDecreaseWidthElement(val density: Density) :
+ ModifierNodeElement<NeverDecreaseWidthNode>() {
override fun create(): NeverDecreaseWidthNode {
return NeverDecreaseWidthNode()
}
override fun update(node: NeverDecreaseWidthNode) {
- error("This should never be called")
+ node.onDensityUpdated()
}
}
private class NeverDecreaseWidthNode : Modifier.Node(), LayoutModifierNode {
private var minWidth = 0
+ fun onDensityUpdated() {
+ // When the font or display size changes, we should re-determine what our minWidth is from
+ // scratch (e.g. if the font size decreased, we may be able to take *less* room).
+ // See b/395607413.
+ minWidth = 0
+ }
+
override fun MeasureScope.measure(
measurable: Measurable,
constraints: Constraints,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index e8ab39692558..d67cb8f81a6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -75,7 +75,12 @@ fun OngoingActivityChip(
}
}
is OngoingActivityChipModel.ClickBehavior.ShowHeadsUpNotification -> {
- ChipBody(model, iconViewStore, onClick = { clickBehavior.onClick() })
+ ChipBody(
+ model,
+ iconViewStore,
+ onClick = { clickBehavior.onClick() },
+ modifier = modifier,
+ )
}
is OngoingActivityChipModel.ClickBehavior.None -> {
@@ -223,6 +228,7 @@ private fun StatusBarIcon(
iconFactory: () -> StatusBarIconView?,
) {
val context = LocalContext.current
+ val colorTintList = ColorStateList.valueOf(colors.text(context))
val iconSizePx =
context.resources.getDimensionPixelSize(
@@ -233,9 +239,9 @@ private fun StatusBarIcon(
factory = { _ ->
iconFactory.invoke()?.apply {
layoutParams = ViewGroup.LayoutParams(iconSizePx, iconSizePx)
- imageTintList = ColorStateList.valueOf(colors.text(context))
} ?: throw IllegalStateException("Missing StatusBarIconView for $notificationKey")
},
+ update = { iconView -> iconView.imageTintList = colorTintList },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
index 3b8c0f48e40e..7080c3402b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
@@ -25,6 +25,7 @@ import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
+import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder
@@ -47,7 +48,13 @@ fun OngoingActivityChips(
chips.active
.filter { !it.isHidden }
.forEach {
- key(it.key) { OngoingActivityChip(model = it, iconViewStore = iconViewStore) }
+ key(it.key) {
+ OngoingActivityChip(
+ model = it,
+ iconViewStore = iconViewStore,
+ modifier = Modifier.sysuiResTag(it.key),
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
index eae2c25d77d8..8228b5533fca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
@@ -555,7 +555,6 @@ constructor(
secondary = DEFAULT_INTERNAL_INACTIVE_MODEL,
)
- // TODO(b/392886257): Support 3 chips if there's space available.
- private const val MAX_VISIBLE_CHIPS = 2
+ private const val MAX_VISIBLE_CHIPS = 3
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
index 9e1686ae135f..03316d3e326c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
@@ -49,7 +49,9 @@ object NewStatusBarIcons {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
index cb1827d57c2a..a58e00c5ee0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
@@ -50,7 +50,9 @@ object StatusBarConnectedDisplays {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
index 4ee49d82b2fd..25dace32261e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
@@ -52,7 +52,9 @@ object StatusBarRootModernization {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
index 27d815190d85..9db2f4b46dae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
@@ -22,6 +22,7 @@ import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModul
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerModule
import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStoreModule
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryModule
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayConfigurationStateModule
import com.android.systemui.statusbar.data.repository.SystemEventChipAnimationControllerStoreModule
import com.android.systemui.statusbar.phone.data.StatusBarPhoneDataLayerModule
import dagger.Module
@@ -34,6 +35,7 @@ import dagger.Module
LightBarControllerStoreModule::class,
RemoteInputRepositoryModule::class,
StatusBarConfigurationControllerModule::class,
+ StatusBarPerDisplayConfigurationStateModule::class,
StatusBarContentInsetsProviderStoreModule::class,
StatusBarModeRepositoryModule::class,
StatusBarPhoneDataLayerModule::class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt
new file mode 100644
index 000000000000..3168a22c56ad
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.common.ui.ConfigurationState
+import com.android.systemui.common.ui.ConfigurationStateImpl
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.data.repository.PerDisplayInstanceProvider
+import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl
+import com.android.systemui.display.data.repository.PerDisplayRepository
+import com.android.systemui.display.data.repository.SingleInstanceRepositoryImpl
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import javax.inject.Inject
+
+@SysUISingleton
+class StatusBarPerDisplayConfigurationStateProvider
+@Inject
+constructor(
+ private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+ private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+ private val factory: ConfigurationStateImpl.Factory,
+) : PerDisplayInstanceProvider<ConfigurationState> {
+
+ override fun createInstance(displayId: Int): ConfigurationState? {
+ val displayWindowProperties =
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
+ val configController =
+ statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+ return factory.create(displayWindowProperties.context, configController)
+ }
+}
+
+@Module
+object StatusBarPerDisplayConfigurationStateModule {
+
+ @Provides
+ @SysUISingleton
+ fun store(
+ instanceProvider: Lazy<StatusBarPerDisplayConfigurationStateProvider>,
+ factory: PerDisplayInstanceRepositoryImpl.Factory<ConfigurationState>,
+ defaultInstance: ConfigurationState,
+ ): PerDisplayRepository<ConfigurationState> {
+ val name = "ConfigurationState"
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ factory.create(name, instanceProvider.get())
+ } else {
+ SingleInstanceRepositoryImpl(name, defaultInstance)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
index 90f97df295f5..ec6508717e8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
@@ -17,51 +17,51 @@
package com.android.systemui.statusbar.featurepods.media.ui.viewmodel
import android.content.Context
+import androidx.compose.runtime.getValue
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.featurepods.media.domain.interactor.MediaControlChipInteractor
import com.android.systemui.statusbar.featurepods.media.shared.model.MediaControlChipModel
import com.android.systemui.statusbar.featurepods.popups.shared.model.HoverBehavior
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipViewModel
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
/**
* [StatusBarPopupChipViewModel] for a media control chip in the status bar. This view model is
* responsible for converting the [MediaControlChipModel] to a [PopupChipModel] that can be used to
* display a media control chip.
*/
-@SysUISingleton
class MediaControlChipViewModel
-@Inject
+@AssistedInject
constructor(
- @Background private val backgroundScope: CoroutineScope,
@Application private val applicationContext: Context,
mediaControlChipInteractor: MediaControlChipInteractor,
-) : StatusBarPopupChipViewModel {
-
+) : StatusBarPopupChipViewModel, ExclusiveActivatable() {
+ private val hydrator: Hydrator = Hydrator("MediaControlChipViewModel.hydrator")
/**
- * A [StateFlow] of the current [PopupChipModel]. This flow emits a new [PopupChipModel]
+ * A snapshot [State] of the current [PopupChipModel]. This emits a new [PopupChipModel]
* whenever the underlying [MediaControlChipModel] changes.
*/
- override val chip: StateFlow<PopupChipModel> =
- mediaControlChipInteractor.mediaControlChipModel
- .map { mediaControlChipModel -> toPopupChipModel(mediaControlChipModel) }
- .stateIn(
- backgroundScope,
- SharingStarted.WhileSubscribed(),
- PopupChipModel.Hidden(PopupChipId.MediaControl),
- )
+ override val chip: PopupChipModel by
+ hydrator.hydratedStateOf(
+ traceName = "chip",
+ initialValue = PopupChipModel.Hidden(PopupChipId.MediaControl),
+ source =
+ mediaControlChipInteractor.mediaControlChipModel.map { model ->
+ toPopupChipModel(model)
+ },
+ )
+
+ override suspend fun onActivated(): Nothing {
+ hydrator.activate()
+ }
private fun toPopupChipModel(model: MediaControlChipModel?): PopupChipModel {
if (model == null || model.songName.isNullOrEmpty()) {
@@ -96,7 +96,12 @@ constructor(
return HoverBehavior.Button(
icon = Icon.Loaded(drawable = icon, contentDescription = contentDescription),
- onIconPressed = { backgroundScope.launch { action.run() } },
+ onIconPressed = { action.run() },
)
}
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): MediaControlChipViewModel
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
index 08a8960f6c96..d1307aa0ee31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
@@ -50,7 +50,9 @@ object StatusBarPopupChips {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipViewModel.kt
index 5712be30ccd6..38f24137d355 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipViewModel.kt
@@ -16,14 +16,14 @@
package com.android.systemui.statusbar.featurepods.popups.ui.viewmodel
+import com.android.systemui.lifecycle.Activatable
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
-import kotlinx.coroutines.flow.StateFlow
/**
* Interface for a view model that knows the display requirements for a single type of status bar
* popup chip.
*/
-interface StatusBarPopupChipViewModel {
- /** A flow modeling the popup chip that should be shown (or not shown). */
- val chip: StateFlow<PopupChipModel>
+interface StatusBarPopupChipViewModel : Activatable {
+ /** A snapshot [State] modeling the popup chip that should be shown (or not shown). */
+ val chip: PopupChipModel
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
index 33bf90defb48..35f1a9981691 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
@@ -21,7 +21,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.android.systemui.lifecycle.ExclusiveActivatable
-import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.MediaControlChipViewModel
import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
@@ -36,18 +35,17 @@ import kotlinx.coroutines.flow.map
*/
class StatusBarPopupChipsViewModel
@AssistedInject
-constructor(mediaControlChip: MediaControlChipViewModel) : ExclusiveActivatable() {
- private val hydrator: Hydrator = Hydrator("StatusBarPopupChipsViewModel.hydrator")
+constructor(mediaControlChipFactory: MediaControlChipViewModel.Factory) : ExclusiveActivatable() {
+
+ private val mediaControlChip by lazy { mediaControlChipFactory.create() }
/** The ID of the current chip that is showing its popup, or `null` if no chip is shown. */
private var currentShownPopupChipId by mutableStateOf<PopupChipId?>(null)
- private val incomingPopupChipBundle: PopupChipBundle by
- hydrator.hydratedStateOf(
- traceName = "incomingPopupChipBundle",
- initialValue = PopupChipBundle(),
- source = mediaControlChip.chip.map { chip -> PopupChipBundle(media = chip) },
- )
+ private val incomingPopupChipBundle: PopupChipBundle by derivedStateOf {
+ val mediaChip = mediaControlChip.chip
+ PopupChipBundle(media = mediaChip)
+ }
val shownPopupChips: List<PopupChipModel.Shown> by derivedStateOf {
if (StatusBarPopupChips.isEnabled) {
@@ -66,7 +64,7 @@ constructor(mediaControlChip: MediaControlChipViewModel) : ExclusiveActivatable(
}
override suspend fun onActivated(): Nothing {
- hydrator.activate()
+ mediaControlChip.activate()
}
private data class PopupChipBundle(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
index 7a985e7fae9a..7b1024ca65dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
@@ -50,7 +50,9 @@ object StatusBarNoHunBehavior {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 4053d065cb16..8be9e410f8f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -124,8 +124,14 @@ public final class NotificationClicker implements View.OnClickListener {
Notification notification = sbn.getNotification();
if (notification.contentIntent != null || notification.fullScreenIntent != null
|| row.getEntry().isBubble()) {
- row.setBubbleClickListener(v ->
- mNotificationActivityStarter.onNotificationBubbleIconClicked(row.getEntry()));
+ if (NotificationBundleUi.isEnabled()) {
+ row.setBubbleClickListener(
+ v -> row.getEntryAdapter().onNotificationBubbleIconClicked());
+ } else {
+ row.setBubbleClickListener(v ->
+ mNotificationActivityStarter.onNotificationBubbleIconClicked(
+ row.getEntry()));
+ }
row.setOnClickListener(this);
row.setOnDragSuccessListener(mOnDragSuccessListener);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
index 6dd44a123538..41353b9921bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
@@ -45,8 +45,6 @@ import kotlinx.coroutines.flow.StateFlowKt;
*/
public class BundleEntry extends PipelineEntry {
- private final BundleEntryAdapter mEntryAdapter;
-
// TODO(b/394483200): move NotificationEntry's implementation to PipelineEntry?
private final MutableStateFlow<Boolean> mSensitive = StateFlowKt.MutableStateFlow(false);
@@ -55,7 +53,6 @@ public class BundleEntry extends PipelineEntry {
public BundleEntry(String key) {
super(key);
- mEntryAdapter = new BundleEntryAdapter();
}
@Nullable
@@ -86,126 +83,9 @@ public class BundleEntry extends PipelineEntry {
return false;
}
- @VisibleForTesting
- public BundleEntryAdapter getEntryAdapter() {
- return mEntryAdapter;
- }
-
- public class BundleEntryAdapter implements EntryAdapter {
-
- /**
- * TODO (b/394483200): convert to PipelineEntry.ROOT_ENTRY when pipeline is migrated?
- */
- @Override
- public GroupEntry getParent() {
- return GroupEntry.ROOT_ENTRY;
- }
-
- @Override
- public boolean isTopLevelEntry() {
- return true;
- }
-
- @NonNull
- @Override
- public String getKey() {
- return mKey;
- }
-
- @Override
- @Nullable
- public ExpandableNotificationRow getRow() {
- return mRow;
- }
-
- @Override
- public boolean isGroupRoot() {
- return true;
- }
-
- @Override
- public StateFlow<Boolean> isSensitive() {
- return BundleEntry.this.mSensitive;
- }
-
- @Override
- public boolean isClearable() {
- // TODO(b/394483200): check whether all of the children are clearable, when implemented
- return true;
- }
-
- @Override
- public int getTargetSdk() {
- return Build.VERSION_CODES.CUR_DEVELOPMENT;
- }
-
- @Override
- public String getSummarization() {
- return null;
- }
-
- @Override
- public int getContrastedColor(Context context, boolean isLowPriority, int backgroundColor) {
- return Notification.COLOR_DEFAULT;
- }
-
- @Override
- public boolean canPeek() {
- return false;
- }
-
- @Override
- public long getWhen() {
- return 0;
- }
-
- @Override
- public IconPack getIcons() {
- // TODO(b/396446620): implement bundle icons
- return null;
- }
-
- @Override
- public boolean isColorized() {
- return false;
- }
-
- @Override
- @Nullable
- public StatusBarNotification getSbn() {
- return null;
- }
-
- @Override
- public boolean canDragAndDrop() {
- return false;
- }
-
- @Override
- public boolean isBubbleCapable() {
- return false;
- }
-
- @Override
- @Nullable
- public String getStyle() {
- return null;
- }
-
- @Override
- public int getSectionBucket() {
- return mBucket;
- }
-
- @Override
- public boolean isAmbient() {
- return false;
- }
-
- @Override
- public boolean isFullScreenCapable() {
- return false;
- }
+ @Nullable
+ public ExpandableNotificationRow getRow() {
+ return mRow;
}
public static final List<BundleEntry> ROOT_BUNDLES = List.of(
@@ -213,4 +93,8 @@ public class BundleEntry extends PipelineEntry {
new BundleEntry(SOCIAL_MEDIA_ID),
new BundleEntry(NEWS_ID),
new BundleEntry(RECS_ID));
+
+ public MutableStateFlow<Boolean> isSensitive() {
+ return mSensitive;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
new file mode 100644
index 000000000000..64db9df8270c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.Notification
+import android.content.Context
+import android.os.Build
+import android.service.notification.StatusBarNotification
+import com.android.systemui.statusbar.notification.icon.IconPack
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import kotlinx.coroutines.flow.StateFlow
+
+class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter {
+ /** TODO (b/394483200): convert to PipelineEntry.ROOT_ENTRY when pipeline is migrated? */
+ override fun getParent(): GroupEntry {
+ return GroupEntry.ROOT_ENTRY
+ }
+
+ override fun isTopLevelEntry(): Boolean {
+ return true
+ }
+
+ override fun getKey(): String {
+ return entry.key
+ }
+
+ override fun getRow(): ExpandableNotificationRow? {
+ return entry.row
+ }
+
+ override fun isGroupRoot(): Boolean {
+ return true
+ }
+
+ override fun isSensitive(): StateFlow<Boolean> {
+ return entry.isSensitive
+ }
+
+ override fun isClearable(): Boolean {
+ // TODO(b/394483200): check whether all of the children are clearable, when implemented
+ return true
+ }
+
+ override fun getTargetSdk(): Int {
+ return Build.VERSION_CODES.CUR_DEVELOPMENT
+ }
+
+ override fun getSummarization(): String? {
+ return null
+ }
+
+ override fun getContrastedColor(
+ context: Context?,
+ isLowPriority: Boolean,
+ backgroundColor: Int,
+ ): Int {
+ return Notification.COLOR_DEFAULT
+ }
+
+ override fun canPeek(): Boolean {
+ return false
+ }
+
+ override fun getWhen(): Long {
+ return 0
+ }
+
+ override fun getIcons(): IconPack? {
+ // TODO(b/396446620): implement bundle icons
+ return null
+ }
+
+ override fun isColorized(): Boolean {
+ return false
+ }
+
+ override fun getSbn(): StatusBarNotification? {
+ return null
+ }
+
+ override fun canDragAndDrop(): Boolean {
+ return false
+ }
+
+ override fun isBubbleCapable(): Boolean {
+ return false
+ }
+
+ override fun getStyle(): String? {
+ return null
+ }
+
+ override fun getSectionBucket(): Int {
+ return entry.bucket
+ }
+
+ override fun isAmbient(): Boolean {
+ return false
+ }
+
+ override fun isFullScreenCapable(): Boolean {
+ return false
+ }
+
+ override fun onNotificationBubbleIconClicked() {
+ // do nothing. these cannot be a bubble
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
index 307a9573d5d8..0e75b6050678 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
@@ -50,7 +50,7 @@ public interface EntryAdapter {
/**
* Gets the view that this entry is backing.
*/
- @NonNull
+ @Nullable
ExpandableNotificationRow getRow();
/**
@@ -135,5 +135,10 @@ public interface EntryAdapter {
default boolean isFullScreenCapable() {
return false;
}
+
+ /**
+ * Process a click on a notification bubble icon
+ */
+ void onNotificationBubbleIconClicked();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt
new file mode 100644
index 000000000000..b7a84ddef103
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+/** Creates an appropriate EntryAdapter for the entry type given */
+interface EntryAdapterFactory {
+ fun create(entry: PipelineEntry): EntryAdapter
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt
new file mode 100644
index 000000000000..779c25a3b402
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.statusbar.notification.NotificationActivityStarter
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
+import javax.inject.Inject
+
+/** Creates an appropriate EntryAdapter for the entry type given */
+class EntryAdapterFactoryImpl
+@Inject
+constructor(
+ private val notificationActivityStarter: NotificationActivityStarter,
+ private val metricsLogger: MetricsLogger,
+ private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
+ private val iconStyleProvider: NotificationIconStyleProvider,
+ private val visualStabilityCoordinator: VisualStabilityCoordinator,
+) : EntryAdapterFactory {
+ override fun create(entry: PipelineEntry): EntryAdapter {
+ return if (entry is NotificationEntry) {
+ NotificationEntryAdapter(
+ notificationActivityStarter,
+ metricsLogger,
+ peopleNotificationIdentifier,
+ iconStyleProvider,
+ visualStabilityCoordinator,
+ entry,
+ )
+ } else {
+ BundleEntryAdapter((entry as BundleEntry))
+ }
+ }
+
+ @VisibleForTesting
+ fun getNotificationActivityStarter() : NotificationActivityStarter {
+ return notificationActivityStarter
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index b19ba3a18826..3d8ba7f335bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -109,7 +109,6 @@ public final class NotificationEntry extends ListEntry {
private final String mKey;
private StatusBarNotification mSbn;
private Ranking mRanking;
- private final NotifEntryAdapter mEntryAdapter;
/*
* Bookkeeping members
@@ -270,141 +269,6 @@ public final class NotificationEntry extends ListEntry {
mKey = sbn.getKey();
setSbn(sbn);
setRanking(ranking);
- mEntryAdapter = new NotifEntryAdapter();
- }
-
- public class NotifEntryAdapter implements EntryAdapter {
- @Override
- public PipelineEntry getParent() {
- return NotificationEntry.this.getParent();
- }
-
- @Override
- public boolean isTopLevelEntry() {
- return getParent() != null
- && (getParent() == ROOT_ENTRY || ROOT_BUNDLES.contains(getParent()));
- }
-
- @Override
- public String getKey() {
- return NotificationEntry.this.getKey();
- }
-
- @Override
- public ExpandableNotificationRow getRow() {
- return NotificationEntry.this.getRow();
- }
-
- @Override
- public boolean isGroupRoot() {
- if (isTopLevelEntry() || getParent() == null) {
- return false;
- }
- if (NotificationEntry.this.getParent() instanceof GroupEntry parentGroupEntry) {
- return parentGroupEntry.getSummary() == NotificationEntry.this;
- }
- return false;
- }
-
- @Override
- public StateFlow<Boolean> isSensitive() {
- return NotificationEntry.this.isSensitive();
- }
-
- @Override
- public boolean isClearable() {
- return NotificationEntry.this.isClearable();
- }
-
- @Override
- public int getTargetSdk() {
- return NotificationEntry.this.targetSdk;
- }
-
- @Override
- public String getSummarization() {
- return getRanking().getSummarization();
- }
-
- @Override
- public void prepareForInflation() {
- getSbn().clearPackageContext();
- }
-
- @Override
- public int getContrastedColor(Context context, boolean isLowPriority, int backgroundColor) {
- return NotificationEntry.this.getContrastedColor(
- context, isLowPriority, backgroundColor);
- }
-
- @Override
- public boolean canPeek() {
- return isStickyAndNotDemoted();
- }
-
- @Override
- public long getWhen() {
- return getSbn().getNotification().getWhen();
- }
-
- @Override
- public IconPack getIcons() {
- return NotificationEntry.this.getIcons();
- }
-
- @Override
- public boolean isColorized() {
- return getSbn().getNotification().isColorized();
- }
-
- @Override
- @Nullable
- public StatusBarNotification getSbn() {
- return NotificationEntry.this.getSbn();
- }
-
- @Override
- public boolean canDragAndDrop() {
- boolean canBubble = canBubble();
- Notification notif = getSbn().getNotification();
- PendingIntent dragIntent = notif.contentIntent != null ? notif.contentIntent
- : notif.fullScreenIntent;
- if (dragIntent != null && dragIntent.isActivity() && !canBubble) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean isBubbleCapable() {
- return NotificationEntry.this.isBubble();
- }
-
- @Override
- @Nullable
- public String getStyle() {
- return getNotificationStyle();
- }
-
- @Override
- public int getSectionBucket() {
- return mBucket;
- }
-
- @Override
- public boolean isAmbient() {
- return mRanking.isAmbient();
- }
-
- @Override
- public boolean isFullScreenCapable() {
- return getSbn().getNotification().fullScreenIntent != null;
- }
-
- }
-
- public EntryAdapter getEntryAdapter() {
- return mEntryAdapter;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
new file mode 100644
index 000000000000..0ff2dd7c7f43
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.content.Context
+import android.service.notification.StatusBarNotification
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.statusbar.notification.NotificationActivityStarter
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator
+import com.android.systemui.statusbar.notification.icon.IconPack
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
+import kotlinx.coroutines.flow.StateFlow
+
+class NotificationEntryAdapter(
+ private val notificationActivityStarter: NotificationActivityStarter,
+ private val metricsLogger: MetricsLogger,
+ private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
+ private val iconStyleProvider: NotificationIconStyleProvider,
+ private val visualStabilityCoordinator: VisualStabilityCoordinator,
+ private val entry: NotificationEntry,
+) : EntryAdapter {
+
+ override fun getParent(): PipelineEntry? {
+ return entry.parent
+ }
+
+ override fun isTopLevelEntry(): Boolean {
+ return parent != null &&
+ (parent === GroupEntry.ROOT_ENTRY || BundleEntry.ROOT_BUNDLES.contains(parent))
+ }
+
+ override fun getKey(): String {
+ return entry.key
+ }
+
+ override fun getRow(): ExpandableNotificationRow {
+ return entry.row
+ }
+
+ override fun isGroupRoot(): Boolean {
+ if (isTopLevelEntry || parent == null) {
+ return false
+ }
+ return (entry.parent as? GroupEntry)?.summary == entry
+ }
+
+ override fun isSensitive(): StateFlow<Boolean> {
+ return entry.isSensitive
+ }
+
+ override fun isClearable(): Boolean {
+ return entry.isClearable
+ }
+
+ override fun getTargetSdk(): Int {
+ return entry.targetSdk
+ }
+
+ override fun getSummarization(): String? {
+ return entry.ranking?.summarization
+ }
+
+ override fun prepareForInflation() {
+ entry.sbn.clearPackageContext()
+ }
+
+ override fun getContrastedColor(
+ context: Context?,
+ isLowPriority: Boolean,
+ backgroundColor: Int,
+ ): Int {
+ return entry.getContrastedColor(context, isLowPriority, backgroundColor)
+ }
+
+ override fun canPeek(): Boolean {
+ return entry.isStickyAndNotDemoted
+ }
+
+ override fun getWhen(): Long {
+ return entry.sbn.notification.getWhen()
+ }
+
+ override fun getIcons(): IconPack {
+ return entry.icons
+ }
+
+ override fun isColorized(): Boolean {
+ return entry.sbn.notification.isColorized
+ }
+
+ override fun getSbn(): StatusBarNotification {
+ return entry.sbn
+ }
+
+ override fun canDragAndDrop(): Boolean {
+ val canBubble: Boolean = entry.canBubble()
+ val notif = entry.sbn.notification
+ val dragIntent =
+ if (notif.contentIntent != null) notif.contentIntent else notif.fullScreenIntent
+ if (dragIntent != null && dragIntent.isActivity && !canBubble) {
+ return true
+ }
+ return false
+ }
+
+ override fun isBubbleCapable(): Boolean {
+ return entry.isBubble
+ }
+
+ override fun getStyle(): String? {
+ return entry.notificationStyle
+ }
+
+ override fun getSectionBucket(): Int {
+ return entry.bucket
+ }
+
+ override fun isAmbient(): Boolean {
+ return entry.ranking.isAmbient
+ }
+
+ override fun isFullScreenCapable(): Boolean {
+ return entry.sbn.notification.fullScreenIntent != null
+ }
+
+ override fun onNotificationBubbleIconClicked() {
+ notificationActivityStarter.onNotificationBubbleIconClicked(entry)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
index 179a87d7f007..cf7881214ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
@@ -50,7 +50,9 @@ object StabilizeHeadsUpGroup {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 53d5dbc58677..ef3da9498f70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -37,6 +37,8 @@ import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory;
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl;
@@ -340,4 +342,8 @@ public interface NotificationsModule {
return MagneticNotificationRowManager.getEmpty();
}
}
+
+ /** Provides an instance of {@link EntryAdapterFactory} */
+ @Binds
+ EntryAdapterFactory provideEntryAdapterFactory(EntryAdapterFactoryImpl impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
index d3a44f9b1497..52bf894c796c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
@@ -50,7 +50,9 @@ object ModesEmptyShadeFix {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
index dbe046fdf30b..90faa4d2c714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
@@ -50,7 +50,9 @@ object NotifRedesignFooter {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
index b5d732117a8f..2f2d80a46f60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
@@ -47,7 +47,7 @@ class HeadsUpAnimator(context: Context, private val systemBarUtilsProxy: SystemB
* of the animation.
*/
fun getHeadsUpYTranslation(isHeadsUpFromBottom: Boolean, hasStatusBarChip: Boolean): Int {
- NotificationsHunSharedAnimationValues.unsafeAssertInNewMode()
+ if (NotificationsHunSharedAnimationValues.isUnexpectedlyInLegacyMode()) return 0
if (isHeadsUpFromBottom) {
// start from or end at the bottom of the screen
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
index c53831671bfc..f52d351cfb0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
@@ -50,7 +50,9 @@ object NotificationsHunSharedAnimationValues {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
index aa81ebf22ac6..147a5afea306 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
@@ -18,11 +18,10 @@ package com.android.systemui.statusbar.notification.icon.ui.viewbinder
import android.view.Display
import androidx.lifecycle.lifecycleScope
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.systemui.common.ui.ConfigurationState
+import com.android.systemui.display.data.repository.PerDisplayRepository
import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
@@ -37,7 +36,8 @@ class NotificationIconContainerStatusBarViewBinder
@Inject
constructor(
private val viewModel: NotificationIconContainerStatusBarViewModel,
- @ShadeDisplayAware private val configuration: ConfigurationState,
+ private val configurationStateRepository: PerDisplayRepository<ConfigurationState>,
+ private val defaultConfigurationState: ConfigurationState,
private val systemBarUtilsState: SystemBarUtilsState,
private val failureTracker: StatusBarIconViewBindingFailureTracker,
private val defaultDisplayViewStore: StatusBarNotificationIconViewStore,
@@ -56,12 +56,14 @@ constructor(
lifecycleScope.launch { it.activate() }
}
}
+ val configurationState: ConfigurationState =
+ configurationStateRepository[displayId] ?: defaultConfigurationState
lifecycleScope.launch {
NotificationIconContainerViewBinder.bind(
displayId = displayId,
view = view,
viewModel = viewModel,
- configuration = configuration,
+ configuration = configurationState,
systemBarUtilsState = systemBarUtilsState,
failureTracker = failureTracker,
viewStore = viewStore,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
index 5bf5766a886c..da59a40a1624 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
@@ -50,7 +50,9 @@ object PromotedNotificationUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
index 8679975998f2..c6e3da1c5750 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
@@ -49,7 +49,9 @@ object PromotedNotificationUiAod {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
index 287e00257bc5..adeddde8ccc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
@@ -50,7 +50,9 @@ object PromotedNotificationUiForceExpanded {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 6837cb2a6292..76d8fb8d3c15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -129,8 +129,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
private void updateColors() {
- if (usesTransparentBackground()) {
- mNormalColor = SurfaceEffectColors.surfaceEffect1(getContext());
+ if (notificationRowTransparency()) {
+ if (mIsBlurSupported) {
+ mNormalColor = SurfaceEffectColors.surfaceEffect1(getContext());
+ } else {
+ mNormalColor = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainer);
+ }
} else {
mNormalColor = mContext.getColor(
com.android.internal.R.color.materialColorSurfaceContainerHigh);
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 987068df3ee9..68ad4fad31c1 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
@@ -111,6 +111,8 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryAdapter;
+import com.android.systemui.statusbar.notification.collection.PipelineEntry;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -121,6 +123,7 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderViewModelImpl;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
@@ -428,7 +431,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
onExpansionChanged(true /* userAction */, wasExpanded);
}
} else if (mEnableNonGroupedNotificationExpand) {
- if (v.isAccessibilityFocused()) {
+ if (v != null && v.isAccessibilityFocused()) {
mPrivateLayout.setFocusOnVisibilityChange();
}
boolean nowExpanded;
@@ -1682,13 +1685,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
if (notificationRowTransparency() && mBackgroundNormal != null) {
if (NotificationBundleUi.isEnabled() && mEntryAdapter != null) {
- mBackgroundNormal.setBgIsColorized(
- usesTransparentBackground() && mEntryAdapter.isColorized());
+ mBackgroundNormal.setBgIsColorized(mEntryAdapter.isColorized());
} else {
if (mEntry != null) {
mBackgroundNormal.setBgIsColorized(
- usesTransparentBackground()
- && mEntry.getSbn().getNotification().isColorized());
+ mEntry.getSbn().getNotification().isColorized());
}
}
}
@@ -1818,6 +1819,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
);
}
+ /**
+ * Init the bundle header view. The ComposeView is initialized within with the passed viewModel.
+ * This can only be init once and not in conjunction with any other header view.
+ */
+ public void initBundleHeader(@NonNull BundleHeaderViewModelImpl bundleHeaderViewModel) {
+ if (NotificationBundleUi.isUnexpectedlyInLegacyMode()) return;
+ NotificationChildrenContainer childrenContainer = getChildrenContainerNonNull();
+ bundleHeaderViewModel.setOnExpandClickListener(mExpandClickListener);
+
+ childrenContainer.initBundleHeader(bundleHeaderViewModel);
+
+ if (TransparentHeaderFix.isEnabled()) {
+ updateBackgroundForGroupState();
+ }
+ }
+
public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
boolean wasAboveShelf = isAboveShelf();
boolean changed = headsUpAnimatingAway != mHeadsupDisappearRunning;
@@ -2124,7 +2141,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* Initialize row.
*/
public void initialize(
- NotificationEntry entry,
+ EntryAdapter entryAdapter,
+ PipelineEntry entry,
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
String appName,
@NonNull String notificationKey,
@@ -2152,11 +2170,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
NotificationRebindingTracker notificationRebindingTracker) {
if (NotificationBundleUi.isEnabled()) {
+ mEntryAdapter = entryAdapter;
// TODO (b/395857098): remove when all usages are migrated
- mEntryAdapter = entry.getEntryAdapter();
- mEntry = entry;
+ mEntry = (NotificationEntry) entry;
} else {
- mEntry = entry;
+ mEntry = (NotificationEntry) entry;
}
mAppName = appName;
mRebindingTracker = notificationRebindingTracker;
@@ -3048,7 +3066,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mUserLocked = userLocked;
mPrivateLayout.setUserExpanding(userLocked);
- mPublicLayout.setUserExpanding(userLocked);
// This is intentionally not guarded with mIsSummaryWithChildren since we might have had
// children but not anymore.
if (mChildrenContainer != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 02e8f4917da4..ac55930f5c11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -45,7 +45,11 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.FeedbackIcon;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory;
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl;
+import com.android.systemui.statusbar.notification.collection.PipelineEntry;
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -56,6 +60,7 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden
import com.android.systemui.statusbar.notification.row.dagger.AppName;
import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -118,8 +123,8 @@ public class ExpandableNotificationRowController implements NotifViewController
private final IStatusBarService mStatusBarService;
private final UiEventLogger mUiEventLogger;
private final MSDLPlayer mMSDLPlayer;
-
private final NotificationSettingsController mSettingsController;
+ private final EntryAdapterFactory mEntryAdapterFactory;
@VisibleForTesting
final NotificationSettingsController.Listener mSettingsListener =
@@ -285,7 +290,8 @@ public class ExpandableNotificationRowController implements NotifViewController
IStatusBarService statusBarService,
UiEventLogger uiEventLogger,
MSDLPlayer msdlPlayer,
- NotificationRebindingTracker notificationRebindingTracker) {
+ NotificationRebindingTracker notificationRebindingTracker,
+ EntryAdapterFactory entryAdapterFactory) {
mView = view;
mListContainer = listContainer;
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
@@ -322,14 +328,16 @@ public class ExpandableNotificationRowController implements NotifViewController
mStatusBarService = statusBarService;
mUiEventLogger = uiEventLogger;
mMSDLPlayer = msdlPlayer;
+ mEntryAdapterFactory = entryAdapterFactory;
}
/**
* Initialize the controller.
*/
- public void init(NotificationEntry entry) {
+ public void init(PipelineEntry entry) {
mActivatableNotificationViewController.init();
mView.initialize(
+ mEntryAdapterFactory.create(entry),
entry,
mRemoteInputViewSubcomponentFactory,
mAppName,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
index 77135802eced..d02f636728fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
@@ -42,14 +42,6 @@ class MagicActionBackgroundDrawable(
private val buttonShape = Path()
// Color and style
- private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
- val bgColor =
- context.getColor(
- com.android.internal.R.color.materialColorPrimaryContainer
- )
- color = bgColor
- style = Paint.Style.FILL
- }
private val outlinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
val outlineColor =
context.getColor(
@@ -99,7 +91,6 @@ class MagicActionBackgroundDrawable(
canvas.save()
// Draw background
canvas.clipPath(buttonShape)
- canvas.drawPath(buttonShape, bgPaint)
// Apply gradient to outline
canvas.drawPath(buttonShape, outlinePaint)
updateGradient(boundsF)
@@ -128,13 +119,11 @@ class MagicActionBackgroundDrawable(
}
override fun setAlpha(alpha: Int) {
- bgPaint.alpha = alpha
outlinePaint.alpha = alpha
invalidateSelf()
}
override fun setColorFilter(colorFilter: ColorFilter?) {
- bgPaint.colorFilter = colorFilter
outlinePaint.colorFilter = colorFilter
invalidateSelf()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index daa598b5f297..51569c1596ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -57,7 +57,6 @@ import com.android.systemui.statusbar.notification.ConversationNotificationProce
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NmSummarizationUiFlag;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.notification.collection.EntryAdapter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded;
@@ -441,8 +440,12 @@ public class NotificationContentInflater implements NotificationRowContentBinder
NotificationRowContentBinderLogger logger) {
return TraceUtils.trace("NotificationContentInflater.createRemoteViews", () -> {
InflationProgress result = new InflationProgress();
+
+ // inflating the contracted view is the legacy invalidation trigger
+ boolean reinflating = (reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0;
// create an image inflater
- result.mRowImageInflater = RowImageInflater.newInstance(row.mImageModelIndex);
+ result.mRowImageInflater = RowImageInflater.newInstance(row.mImageModelIndex,
+ reinflating);
if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
logger.logAsyncTaskProgress(row.getLoggingKey(), "creating contracted remote view");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 3586078c9e82..482b315aa14d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -499,7 +499,10 @@ constructor(
logger.logAsyncTaskProgress(entry.logKey, "loading RON images")
inflationProgress.rowImageInflater.loadImagesSynchronously(packageContext)
- logger.logAsyncTaskProgress(entry.logKey, "getting row image resolver (on wrong thread!)")
+ logger.logAsyncTaskProgress(
+ entry.logKey,
+ "getting row image resolver (on wrong thread!)",
+ )
val imageResolver = row.imageResolver
// wait for image resolver to finish preloading
logger.logAsyncTaskProgress(entry.logKey, "waiting for preloaded images")
@@ -685,13 +688,17 @@ constructor(
logger: NotificationRowContentBinderLogger,
): InflationProgress {
val rowImageInflater =
- RowImageInflater.newInstance(previousIndex = row.mImageModelIndex)
+ RowImageInflater.newInstance(
+ previousIndex = row.mImageModelIndex,
+ // inflating the contracted view is the legacy invalidation trigger
+ reinflating = reInflateFlags and FLAG_CONTENT_VIEW_CONTRACTED != 0,
+ )
val promotedContent =
if (PromotedNotificationContentModel.featureFlagEnabled()) {
logger.logAsyncTaskProgress(
entry.logKey,
- "extracting promoted notification content"
+ "extracting promoted notification content",
)
val imageModelProvider = rowImageInflater.useForContentModel()
promotedNotificationContentExtractor
@@ -750,7 +757,7 @@ constructor(
) {
logger.logAsyncTaskProgress(
entry.logKey,
- "inflating public single line view model"
+ "inflating public single line view model",
)
if (bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT) {
SingleLineViewInflater.inflateSingleLineViewModel(
@@ -852,18 +859,12 @@ constructor(
} else null
val expanded =
if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
- logger.logAsyncTaskProgress(
- row.loggingKey,
- "creating expanded remote view",
- )
+ logger.logAsyncTaskProgress(row.loggingKey, "creating expanded remote view")
createExpandedView(builder, bindParams.isMinimized)
} else null
val headsUp =
if (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0) {
- logger.logAsyncTaskProgress(
- row.loggingKey,
- "creating heads up remote view",
- )
+ logger.logAsyncTaskProgress(row.loggingKey, "creating heads up remote view")
val isHeadsUpCompact = headsUpStyleProvider.shouldApplyCompactStyle()
if (isHeadsUpCompact) {
builder.createCompactHeadsUpContentView()
@@ -873,10 +874,7 @@ constructor(
} else null
val public =
if (reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC != 0) {
- logger.logAsyncTaskProgress(
- row.loggingKey,
- "creating public remote view"
- )
+ logger.logAsyncTaskProgress(row.loggingKey, "creating public remote view")
if (
LockscreenOtpRedaction.isEnabled &&
bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT
@@ -1142,7 +1140,7 @@ constructor(
override fun setResultView(v: View) {
logger.logAsyncTaskProgress(
entry.logKey,
- "group header view applied"
+ "group header view applied",
)
result.inflatedGroupHeaderView = v as NotificationHeaderView?
}
@@ -1198,7 +1196,7 @@ constructor(
}
logger.logAsyncTaskProgress(
entry.logKey,
- "applying low priority group header view"
+ "applying low priority group header view",
)
applyRemoteView(
inflationExecutor = inflationExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt
index 95ef60fdcefe..7bac17f4c227 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt
@@ -83,9 +83,9 @@ interface RowImageInflater {
inline fun featureFlagEnabled() = PromotedNotificationUiAod.isEnabled
@JvmStatic
- fun newInstance(previousIndex: ImageModelIndex?): RowImageInflater =
+ fun newInstance(previousIndex: ImageModelIndex?, reinflating: Boolean): RowImageInflater =
if (featureFlagEnabled()) {
- RowImageInflaterImpl(previousIndex)
+ RowImageInflaterImpl(previousIndex, reinflating)
} else {
RowImageInflaterStub
}
@@ -110,7 +110,8 @@ private object RowImageInflaterStub : RowImageInflater {
override fun getNewImageIndex(): ImageModelIndex? = null
}
-class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?) : RowImageInflater {
+class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?, val reinflating: Boolean) :
+ RowImageInflater {
private val providedImages = mutableListOf<LazyImage>()
/**
@@ -139,10 +140,15 @@ class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?) : RowIma
// ensure all entries are stored
providedImages.add(newImage)
// load the image result from the index into our new object
- previousIndex?.findImage(iconData, sizeClass, transform)?.let {
- // copy the result into our new object
- newImage.result = it
- }
+ previousIndex
+ // skip the cached image when we are "reinflating" to avoid stale content
+ // being displayed from the same URI after the app updated the notif
+ ?.takeUnless { reinflating }
+ ?.findImage(iconData, sizeClass, transform)
+ ?.let {
+ // copy the result into our new object
+ newImage.result = it
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
index 11c942c9bcc0..37212a387fad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
@@ -49,7 +49,9 @@ object NotificationBundleUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
@@ -57,4 +59,4 @@ object NotificationBundleUi {
*/
@JvmStatic
inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
-} \ No newline at end of file
+}
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 e830d18b7d73..315d37e55bc3 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
@@ -39,9 +39,11 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.compose.ui.platform.ComposeView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.NotificationExpandButton;
+import com.android.systemui.notifications.ui.composable.row.BundleHeaderKt;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -58,6 +60,7 @@ import com.android.systemui.statusbar.notification.row.HybridGroupManager;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderViewModelImpl;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
@@ -119,6 +122,13 @@ public class NotificationChildrenContainer extends ViewGroup
*/
private boolean mEnableShadowOnChildNotifications;
+ /**
+ * This view is only set when this NCC is a bundle. If this view is set, all other header
+ * view variants have to be null.
+ */
+ private ComposeView mBundleHeaderView;
+ private BundleHeaderViewModelImpl mBundleHeaderViewModel;
+
private NotificationHeaderView mGroupHeader;
private NotificationHeaderViewWrapper mGroupHeaderWrapper;
private NotificationHeaderView mMinimizedGroupHeader;
@@ -189,6 +199,9 @@ public class NotificationChildrenContainer extends ViewGroup
R.dimen.notification_children_container_top_padding);
mHeaderHeight = mCollapsedHeaderMargin + mAdditionalExpandedHeaderMargin;
}
+ if (mBundleHeaderView != null) {
+ initBundleDimens();
+ }
mCollapsedBottomPadding = res.getDimensionPixelOffset(
R.dimen.notification_children_collapsed_bottom_padding);
mEnableShadowOnChildNotifications =
@@ -244,6 +257,10 @@ public class NotificationChildrenContainer extends ViewGroup
mMinimizedGroupHeader.getMeasuredWidth(),
mMinimizedGroupHeader.getMeasuredHeight());
}
+ if (mBundleHeaderView != null) {
+ mBundleHeaderView.layout(0, 0, mBundleHeaderView.getMeasuredWidth(),
+ mBundleHeaderView.getMeasuredHeight());
+ }
}
@Override
@@ -295,6 +312,9 @@ public class NotificationChildrenContainer extends ViewGroup
if (mMinimizedGroupHeader != null) {
mMinimizedGroupHeader.measure(widthMeasureSpec, headerHeightSpec);
}
+ if (mBundleHeaderView != null) {
+ mBundleHeaderView.measure(widthMeasureSpec, headerHeightSpec);
+ }
setMeasuredDimension(width, height);
Trace.endSection();
@@ -489,6 +509,28 @@ public class NotificationChildrenContainer extends ViewGroup
}
/**
+ * Init the bundle header view. The ComposeView is initialized within with the passed viewModel.
+ * This can only be init once and not in conjunction with any other header view.
+ */
+ public void initBundleHeader(@NonNull BundleHeaderViewModelImpl viewModel) {
+ if (NotificationBundleUi.isUnexpectedlyInLegacyMode()) return;
+ if (mBundleHeaderView != null) return;
+ initBundleDimens();
+
+ mBundleHeaderViewModel = viewModel;
+ mBundleHeaderView = BundleHeaderKt.createComposeView(mBundleHeaderViewModel, getContext());
+ addView(mBundleHeaderView);
+ invalidate();
+ }
+
+ private void initBundleDimens() {
+ NotificationBundleUi.unsafeAssertInNewMode();
+ mCollapsedHeaderMargin = mHeaderHeight;
+ mAdditionalExpandedHeaderMargin = 0;
+ mCollapsedBottomPadding = 0;
+ }
+
+ /**
* Set the group header view
* @param headerView view to set
* @param onClickListener OnClickListener of the header view
@@ -1311,6 +1353,17 @@ public class NotificationChildrenContainer extends ViewGroup
mGroupHeader.setHeaderBackgroundDrawable(null);
}
}
+ if (mBundleHeaderView != null) {
+ if (expanded) {
+ ColorDrawable cd = new ColorDrawable();
+ cd.setColor(mContainingNotification.calculateBgColor());
+ // TODO(b/389839492): The backgroundDrawable needs an outline like in the original:
+ // setOutlineProvider(mProvider);
+ mBundleHeaderViewModel.setBackgroundDrawable(cd);
+ } else {
+ mBundleHeaderViewModel.setBackgroundDrawable(null);
+ }
+ }
}
public int getMaxContentHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 531baa8dc302..c2c271bd6e81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -1290,7 +1290,9 @@ public class NotificationStackScrollLayout
@Override
public void setHeadsUpBottom(float headsUpBottom) {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
- if (mAmbientState.getHeadsUpBottom() != headsUpBottom) {
+ if (NotificationsHunSharedAnimationValues.isEnabled()) {
+ mHeadsUpAnimator.setHeadsUpAppearHeightBottom(Math.round(headsUpBottom));
+ } else if (mAmbientState.getHeadsUpBottom() != headsUpBottom) {
mAmbientState.setHeadsUpBottom(headsUpBottom);
mStateAnimator.setHeadsUpAppearHeightBottom(Math.round(headsUpBottom));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index a277597e23df..c1aa5f12aa99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -266,7 +266,7 @@ constructor(
combine(shadeModeInteractor.shadeMode, shadeInteractor.qsExpansion) { shadeMode, qsExpansion
->
when (shadeMode) {
- is ShadeMode.Dual -> false
+ is ShadeMode.Dual,
is ShadeMode.Split -> true
is ShadeMode.Single -> qsExpansion < 0.5f
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index face1c7512ce..fc721bfae369 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -109,6 +109,7 @@ import com.android.systemui.AutoReinflateContainer;
import com.android.systemui.CoreStartable;
import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogTags;
+import com.android.systemui.Flags;
import com.android.systemui.InitController;
import com.android.systemui.Prefs;
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
@@ -3183,12 +3184,27 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
new ActivityTransitionAnimator.Listener() {
@Override
public void onTransitionAnimationStart() {
- mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
+ if (!Flags.notificationShadeBlur() || !Flags.moveTransitionAnimationLayer()) {
+ mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
+ }
+ }
+
+ @Override
+ public void onTransitionAnimationProgress(float linearProgress) {
+ if (Flags.notificationShadeBlur() && Flags.moveTransitionAnimationLayer()) {
+ mNotificationShadeDepthControllerLazy.get()
+ .onTransitionAnimationProgress(linearProgress);
+ }
}
@Override
public void onTransitionAnimationEnd() {
- mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
+ if (Flags.notificationShadeBlur() && Flags.moveTransitionAnimationLayer()) {
+ mNotificationShadeDepthControllerLazy.get()
+ .onTransitionAnimationEnd();
+ } else {
+ mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
+ }
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
index 6afcd8a4fad8..0ac87178086f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
@@ -52,7 +52,9 @@ object StatusBarChipsModernization {
* the flag is not enabled to ensure that the refactor author catches issues in testing.
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractor.kt
index d53cbabb1d19..342adc6af003 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractor.kt
@@ -65,12 +65,12 @@ class BatteryInteractor @Inject constructor(repo: BatteryRepository) {
*/
val batteryAttributionType =
combine(isCharging, powerSave, isBatteryDefenderEnabled) { charging, powerSave, defend ->
- if (charging) {
- BatteryAttributionModel.Charging
- } else if (powerSave) {
+ if (powerSave) {
BatteryAttributionModel.PowerSave
} else if (defend) {
BatteryAttributionModel.Defend
+ } else if (charging) {
+ BatteryAttributionModel.Charging
} else {
null
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
index 1d1cfd6cdf68..b2d314c3590b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
@@ -50,7 +50,9 @@ object StatusBarSignalPolicyRefactorEthernet {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 2efc0579f333..d6105c2bd93f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -192,20 +192,16 @@ constructor(
override val isDeviceEmergencyCallCapable: StateFlow<Boolean> =
serviceStateChangedEvent
.mapLatest {
- val modems = telephonyManager.activeModemCount
-
- // Assume false for automotive devices which don't have the calling feature.
- // TODO: b/398045526 to revisit the below.
- val isAutomotive: Boolean =
- context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- val hasFeatureCalling: Boolean =
+ // TODO(b/400460777): check for hasSystemFeature only once
+ val hasRadioAccess: Boolean =
context.packageManager.hasSystemFeature(
- PackageManager.FEATURE_TELEPHONY_CALLING
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS
)
- if (isAutomotive && !hasFeatureCalling) {
+ if (!hasRadioAccess) {
return@mapLatest false
}
+ val modems = telephonyManager.activeModemCount
// Check the service state for every modem. If any state reports emergency calling
// capable, then consider the device to have emergency call capabilities
(0..<modems)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
index cdd02865bbee..cfd50973924d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
@@ -258,7 +258,7 @@ constructor(
if (SceneContainerFlag.isEnabled) {
listener?.let { listener ->
launch {
- viewModel.isHomeStatusBarAllowedByScene.collect {
+ viewModel.isHomeStatusBarAllowed.collect {
listener.onIsHomeStatusBarAllowedBySceneChanged(it)
}
}
@@ -503,7 +503,7 @@ interface StatusBarVisibilityChangeListener {
/**
* Called when the scene state has changed such that the home status bar is newly allowed or no
- * longer allowed. See [HomeStatusBarViewModel.isHomeStatusBarAllowedByScene].
+ * longer allowed. See [HomeStatusBarViewModel.isHomeStatusBarAllowed].
*/
fun onIsHomeStatusBarAllowedBySceneChanged(isHomeStatusBarAllowedByScene: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index 9975aff938d6..3bae91a0ebe3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
import android.annotation.ColorInt
import android.graphics.Rect
+import android.view.Display
import android.view.View
import androidx.compose.runtime.getValue
import com.android.app.tracing.coroutines.launchTraced as launch
@@ -41,7 +42,9 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.domain.interactor.ShadeDisplaysInteractor
import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.MediaProjectionStopDialogModel
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel
@@ -73,6 +76,7 @@ import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
+import javax.inject.Provider
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.awaitCancellation
@@ -142,13 +146,12 @@ interface HomeStatusBarViewModel : Activatable {
val popupChips: List<PopupChipModel.Shown>
/**
- * True if the current scene can show the home status bar (aka this status bar), and false if
- * the current scene should never show the home status bar.
+ * True if the status bar should be visible.
*
* TODO(b/364360986): Once the is<SomeChildView>Visible flows are fully enabled, we shouldn't
* need this flow anymore.
*/
- val isHomeStatusBarAllowedByScene: StateFlow<Boolean>
+ val isHomeStatusBarAllowed: StateFlow<Boolean>
/** True if the home status bar is showing, and there is no HUN happening */
val canShowOngoingActivityChips: Flow<Boolean>
@@ -222,6 +225,7 @@ constructor(
statusBarContentInsetsViewModelStore: StatusBarContentInsetsViewModelStore,
@Background bgScope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
+ shadeDisplaysInteractor: Provider<ShadeDisplaysInteractor>,
) : HomeStatusBarViewModel, ExclusiveActivatable() {
private val hydrator = Hydrator(traceName = "HomeStatusBarViewModel.hydrator")
@@ -258,12 +262,44 @@ constructor(
override val popupChips
get() = statusBarPopupChips.shownPopupChips
- override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
+ /**
+ * Whether the display of this statusbar has the shade window (that is hosting shade container
+ * and lockscreen, among other things).
+ */
+ private val isShadeWindowOnThisDisplay =
+ if (ShadeWindowGoesAround.isEnabled) {
+ shadeDisplaysInteractor.get().displayId.map { shadeDisplayId ->
+ thisDisplayId == shadeDisplayId
+ }
+ } else {
+ // Shade doesn't move anywhere, it is always on the default display.
+ flowOf(thisDisplayId == Display.DEFAULT_DISPLAY)
+ }
+
+ private val isShadeVisibleOnAnyDisplay =
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.currentOverlays.map { currentOverlays ->
+ (Overlays.NotificationsShade in currentOverlays ||
+ Overlays.QuickSettingsShade in currentOverlays)
+ }
+ } else {
+ shadeInteractor.isAnyFullyExpanded
+ }
+
+ private val isShadeVisibleOnThisDisplay: Flow<Boolean> =
+ combine(isShadeWindowOnThisDisplay, isShadeVisibleOnAnyDisplay) {
+ hasShade,
+ isShadeVisibleOnAnyDisplay ->
+ hasShade && isShadeVisibleOnAnyDisplay
+ }
+
+ private val isHomeStatusBarAllowedByScene: Flow<Boolean> =
combine(
sceneInteractor.currentScene,
- sceneInteractor.currentOverlays,
+ isShadeVisibleOnThisDisplay,
sceneContainerOcclusionInteractor.invisibleDueToOcclusion,
- ) { currentScene, currentOverlays, isOccluded ->
+ ) { currentScene, isShadeVisible, isOccluded ->
+
// All scenes have their own status bars, so we should only show the home status bar
// if we're not in a scene. There are two exceptions:
// 1) The shade (notifications or quick settings) is shown, because it has its own
@@ -271,9 +307,7 @@ constructor(
// 2) If the scene is occluded, then the occluding app needs to show the status bar.
// (Fullscreen apps actually won't show the status bar but that's handled with the
// rest of our fullscreen app logic, which lives elsewhere.)
- (currentScene == Scenes.Gone &&
- Overlays.NotificationsShade !in currentOverlays &&
- Overlays.QuickSettingsShade !in currentOverlays) || isOccluded
+ (currentScene == Scenes.Gone && !isShadeVisible) || isOccluded
}
.distinctUntilChanged()
.logDiffsForTable(
@@ -281,7 +315,6 @@ constructor(
columnName = COL_ALLOWED_BY_SCENE,
initialValue = false,
)
- .stateIn(bgScope, SharingStarted.WhileSubscribed(), initialValue = false)
override val areNotificationsLightsOut: Flow<Boolean> =
if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) {
@@ -330,21 +363,29 @@ constructor(
* if we shouldn't be showing any part of the home status bar.
*/
private val isHomeScreenStatusBarAllowedLegacy: Flow<Boolean> =
- combine(
- keyguardTransitionInteractor.currentKeyguardState,
- shadeInteractor.isAnyFullyExpanded,
- ) { currentKeyguardState, isShadeExpanded ->
- (currentKeyguardState == GONE || currentKeyguardState == OCCLUDED) && !isShadeExpanded
+ combine(keyguardTransitionInteractor.currentKeyguardState, isShadeVisibleOnThisDisplay) {
+ currentKeyguardState,
+ isShadeVisibleOnThisDisplay ->
+ (currentKeyguardState == GONE || currentKeyguardState == OCCLUDED) &&
+ !isShadeVisibleOnThisDisplay
// TODO(b/364360986): Add edge cases, like secure camera launch.
}
- private val isHomeStatusBarAllowed: Flow<Boolean> =
+ // "Compat" to cover both legacy and Scene container case in one flow.
+ private val isHomeStatusBarAllowedCompat =
if (SceneContainerFlag.isEnabled) {
isHomeStatusBarAllowedByScene
} else {
isHomeScreenStatusBarAllowedLegacy
}
+ override val isHomeStatusBarAllowed =
+ isHomeStatusBarAllowedCompat.stateIn(
+ bgScope,
+ SharingStarted.WhileSubscribed(),
+ initialValue = false,
+ )
+
private val shouldHomeStatusBarBeVisible =
combine(
isHomeStatusBarAllowed,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTileGrid.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTileGrid.kt
index 16f24f1d5821..5d7ce91b332c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTileGrid.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTileGrid.kt
@@ -34,7 +34,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.systemui.Flags
-import com.android.systemui.qs.panels.ui.compose.PagerDots
+import com.android.systemui.common.ui.compose.PagerDots
import com.android.systemui.statusbar.policy.ui.dialog.viewmodel.ModesDialogViewModel
@Composable
diff --git a/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
index 59c05c2493c3..a94d51a21af3 100644
--- a/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
+++ b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
@@ -50,7 +50,9 @@ object DeprecateDpmSupervisionApis {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
+ @Deprecated("Avoid crashing.", ReplaceWith("if (this.isUnexpectedlyInLegacyMode()) return"))
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
index bb8fe46be5b0..3ac6c7bc0c6b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
@@ -28,7 +28,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.volume.Events
-import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogComponentFactory
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import javax.inject.Inject
import kotlinx.coroutines.awaitCancellation
@@ -37,7 +37,7 @@ class VolumeDialog
@Inject
constructor(
@Application context: Context,
- private val componentFactory: VolumeDialogComponent.Factory,
+ private val componentFactory: VolumeDialogComponentFactory,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
) : ComponentDialog(context, R.style.Theme_SystemUI_Dialog_Volume) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
index 434f6b567048..36b2b48ece21 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.dialog.dagger
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogComponentFactory
import com.android.systemui.volume.dialog.dagger.module.VolumeDialogModule
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
@@ -38,9 +39,9 @@ interface VolumeDialogComponent {
fun sliderComponentFactory(): VolumeDialogSliderComponent.Factory
@Subcomponent.Factory
- interface Factory {
+ interface Factory : VolumeDialogComponentFactory {
- fun create(
+ override fun create(
/**
* Provides a coroutine scope to use inside [VolumeDialogScope].
* [com.android.systemui.volume.dialog.VolumeDialogPlugin] manages the lifecycle of this
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogComponentFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogComponentFactory.kt
new file mode 100644
index 000000000000..d909f26dd1dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogComponentFactory.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.volume.dialog.dagger.factory
+
+import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import kotlinx.coroutines.CoroutineScope
+
+/** Common interface for all dagger Subcomponent.Factory providing [VolumeDialogComponent]. */
+interface VolumeDialogComponentFactory {
+
+ fun create(scope: CoroutineScope): VolumeDialogComponent
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogModule.kt
index 7b08317d5265..fcf4d110f269 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogModule.kt
@@ -16,10 +16,12 @@
package com.android.systemui.volume.dialog.dagger.module
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.ringer.data.repository.VolumeDialogRingerFeedbackRepository
import com.android.systemui.volume.dialog.ringer.data.repository.VolumeDialogRingerFeedbackRepositoryImpl
import com.android.systemui.volume.dialog.ringer.ui.binder.VolumeDialogRingerViewBinder
import com.android.systemui.volume.dialog.settings.ui.binder.VolumeDialogSettingsButtonViewBinder
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSlidersViewBinder
import com.android.systemui.volume.dialog.ui.binder.ViewBinder
import dagger.Binds
@@ -27,7 +29,7 @@ import dagger.Module
import dagger.Provides
/** Dagger module for volume dialog code in the volume package */
-@Module
+@Module(subcomponents = [VolumeDialogSliderComponent::class])
interface VolumeDialogModule {
@Binds
@@ -38,6 +40,7 @@ interface VolumeDialogModule {
companion object {
@Provides
+ @VolumeDialog
fun provideViewBinders(
slidersViewBinder: VolumeDialogSlidersViewBinder,
ringerViewBinder: VolumeDialogRingerViewBinder,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
index 547c51d1cefd..35752ae08260 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.volume.dialog.dagger.module
import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogComponentFactory
import com.android.systemui.volume.dialog.shared.model.CsdWarningConfigModel
import com.android.systemui.volume.dialog.utils.VolumeTracer
import com.android.systemui.volume.dialog.utils.VolumeTracerImpl
@@ -27,6 +28,11 @@ import dagger.Provides
@Module(subcomponents = [VolumeDialogComponent::class])
interface VolumeDialogPluginModule {
+ @Binds
+ fun bindVolumeDialogComponentFactory(
+ factory: VolumeDialogComponent.Factory
+ ): VolumeDialogComponentFactory
+
@Binds fun bindVolumeTracer(volumeTracer: VolumeTracerImpl): VolumeTracer
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
index 577e47bb3b83..d0ed24d0b86d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
@@ -19,6 +19,7 @@ package com.android.systemui.volume.dialog.sliders.dagger
import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogOverscrollViewBinder
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
import dagger.BindsInstance
import dagger.Subcomponent
@@ -34,6 +35,8 @@ interface VolumeDialogSliderComponent {
fun overscrollViewBinder(): VolumeDialogOverscrollViewBinder
+ fun sliderViewModel(): VolumeDialogSliderViewModel
+
@Subcomponent.Factory
interface Factory {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
index 5de8fe54505f..11d9df4294c0 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
@@ -37,6 +37,7 @@ import com.android.systemui.common.ui.view.onApplyWindowInsets
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.awaitCancellationThenDispose
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.ui.utils.JankListenerFactory
@@ -72,7 +73,7 @@ constructor(
private val viewModel: VolumeDialogViewModel,
private val jankListenerFactory: JankListenerFactory,
private val tracer: VolumeTracer,
- private val viewBinders: List<@JvmSuppressWildcards ViewBinder>,
+ @VolumeDialog private val viewBinders: List<@JvmSuppressWildcards ViewBinder>,
) {
private val halfOpenedOffsetPx: Float =
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withAnimator.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
index aa8044515ea2..aa8044515ea2 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withAnimator.json
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withAnimator.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
index aa8044515ea2..aa8044515ea2 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withAnimator.json
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
index 7abff2c74531..5476160df156 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
@@ -371,14 +371,5 @@
0
]
}
- ],
- "\/\/metadata": {
- "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenLaunching_withSpring.json",
- "goldenIdentifier": "backgroundAnimation_whenLaunching_withSpring",
- "testClassName": "TransitionAnimatorTest",
- "testMethodName": "backgroundAnimation_whenLaunching[true]",
- "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
- "result": "FAILED",
- "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenLaunching_withSpring.actual.mp4"
- }
+ ]
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
index 561961145ca1..5476160df156 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -371,14 +371,5 @@
0
]
}
- ],
- "\/\/metadata": {
- "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenReturning_withSpring.json",
- "goldenIdentifier": "backgroundAnimation_whenReturning_withSpring",
- "testClassName": "TransitionAnimatorTest",
- "testMethodName": "backgroundAnimation_whenReturning[true]",
- "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
- "result": "FAILED",
- "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenReturning_withSpring.actual.mp4"
- }
+ ]
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..aa8044515ea2
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..5476160df156
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 45,
+ 126,
+ 190,
+ 228,
+ 246,
+ 253,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withAnimator.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
index 7f623575fef4..7f623575fef4 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withAnimator.json
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..41a46df55e38
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
index 63c263175122..848c7d460d3b 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
@@ -371,14 +371,5 @@
0
]
}
- ],
- "\/\/metadata": {
- "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimationWithoutFade_whenReturning_withSpring.json",
- "goldenIdentifier": "backgroundAnimationWithoutFade_whenReturning_withSpring",
- "testClassName": "TransitionAnimatorTest",
- "testMethodName": "backgroundAnimationWithoutFade_whenReturning[true]",
- "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
- "result": "FAILED",
- "videoLocation": "TransitionAnimatorTest\/backgroundAnimationWithoutFade_whenReturning_withSpring.actual.mp4"
- }
+ ]
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
index 825190ba7a32..848c7d460d3b 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -371,14 +371,5 @@
0
]
}
- ],
- "\/\/metadata": {
- "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimationWithoutFade_whenLaunching_withSpring.json",
- "goldenIdentifier": "backgroundAnimationWithoutFade_whenLaunching_withSpring",
- "testClassName": "TransitionAnimatorTest",
- "testMethodName": "backgroundAnimationWithoutFade_whenLaunching[true]",
- "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
- "result": "FAILED",
- "videoLocation": "TransitionAnimatorTest\/backgroundAnimationWithoutFade_whenLaunching_withSpring.actual.mp4"
- }
+ ]
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withAnimator.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
index 98005c53f6e0..98005c53f6e0 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withAnimator.json
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..98005c53f6e0
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..7f623575fef4
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..7f623575fef4
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 96,
+ 153,
+ 192,
+ 220,
+ 238,
+ 249,
+ 254,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenLaunching_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..98005c53f6e0
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..98005c53f6e0
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withAnimator_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,492 @@
+{
+ "frame_ids": [
+ 0,
+ 20,
+ 40,
+ 60,
+ 80,
+ 100,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 300,
+ 320,
+ 340,
+ 360,
+ 380,
+ 400,
+ 420,
+ 440,
+ 460,
+ 480,
+ 500
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 100,
+ "top": 300,
+ "right": 200,
+ "bottom": 400
+ },
+ {
+ "left": 99,
+ "top": 296,
+ "right": 202,
+ "bottom": 404
+ },
+ {
+ "left": 95,
+ "top": 283,
+ "right": 207,
+ "bottom": 417
+ },
+ {
+ "left": 86,
+ "top": 256,
+ "right": 219,
+ "bottom": 443
+ },
+ {
+ "left": 68,
+ "top": 198,
+ "right": 243,
+ "bottom": 499
+ },
+ {
+ "left": 39,
+ "top": 110,
+ "right": 278,
+ "bottom": 584
+ },
+ {
+ "left": 26,
+ "top": 74,
+ "right": 292,
+ "bottom": 618
+ },
+ {
+ "left": 19,
+ "top": 55,
+ "right": 299,
+ "bottom": 637
+ },
+ {
+ "left": 15,
+ "top": 42,
+ "right": 304,
+ "bottom": 649
+ },
+ {
+ "left": 12,
+ "top": 33,
+ "right": 307,
+ "bottom": 658
+ },
+ {
+ "left": 9,
+ "top": 27,
+ "right": 310,
+ "bottom": 664
+ },
+ {
+ "left": 7,
+ "top": 21,
+ "right": 312,
+ "bottom": 669
+ },
+ {
+ "left": 6,
+ "top": 17,
+ "right": 314,
+ "bottom": 674
+ },
+ {
+ "left": 5,
+ "top": 13,
+ "right": 315,
+ "bottom": 677
+ },
+ {
+ "left": 4,
+ "top": 10,
+ "right": 316,
+ "bottom": 680
+ },
+ {
+ "left": 3,
+ "top": 8,
+ "right": 317,
+ "bottom": 682
+ },
+ {
+ "left": 2,
+ "top": 6,
+ "right": 318,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 5,
+ "right": 318,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 319,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 1,
+ "top": 2,
+ "right": 319,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 1,
+ "right": 320,
+ "bottom": 689
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ },
+ {
+ "left": 0,
+ "top": 0,
+ "right": 320,
+ "bottom": 690
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ {
+ "top_left_x": 10,
+ "top_left_y": 10,
+ "top_right_x": 10,
+ "top_right_y": 10,
+ "bottom_right_x": 20,
+ "bottom_right_y": 20,
+ "bottom_left_x": 20,
+ "bottom_left_y": 20
+ },
+ {
+ "top_left_x": 9.865689,
+ "top_left_y": 9.865689,
+ "top_right_x": 9.865689,
+ "top_right_y": 9.865689,
+ "bottom_right_x": 19.731379,
+ "bottom_right_y": 19.731379,
+ "bottom_left_x": 19.731379,
+ "bottom_left_y": 19.731379
+ },
+ {
+ "top_left_x": 9.419104,
+ "top_left_y": 9.419104,
+ "top_right_x": 9.419104,
+ "top_right_y": 9.419104,
+ "bottom_right_x": 18.838207,
+ "bottom_right_y": 18.838207,
+ "bottom_left_x": 18.838207,
+ "bottom_left_y": 18.838207
+ },
+ {
+ "top_left_x": 8.533693,
+ "top_left_y": 8.533693,
+ "top_right_x": 8.533693,
+ "top_right_y": 8.533693,
+ "bottom_right_x": 17.067387,
+ "bottom_right_y": 17.067387,
+ "bottom_left_x": 17.067387,
+ "bottom_left_y": 17.067387
+ },
+ {
+ "top_left_x": 6.5919456,
+ "top_left_y": 6.5919456,
+ "top_right_x": 6.5919456,
+ "top_right_y": 6.5919456,
+ "bottom_right_x": 13.183891,
+ "bottom_right_y": 13.183891,
+ "bottom_left_x": 13.183891,
+ "bottom_left_y": 13.183891
+ },
+ {
+ "top_left_x": 3.6674318,
+ "top_left_y": 3.6674318,
+ "top_right_x": 3.6674318,
+ "top_right_y": 3.6674318,
+ "bottom_right_x": 7.3348637,
+ "bottom_right_y": 7.3348637,
+ "bottom_left_x": 7.3348637,
+ "bottom_left_y": 7.3348637
+ },
+ {
+ "top_left_x": 2.4832253,
+ "top_left_y": 2.4832253,
+ "top_right_x": 2.4832253,
+ "top_right_y": 2.4832253,
+ "bottom_right_x": 4.9664507,
+ "bottom_right_y": 4.9664507,
+ "bottom_left_x": 4.9664507,
+ "bottom_left_y": 4.9664507
+ },
+ {
+ "top_left_x": 1.8252907,
+ "top_left_y": 1.8252907,
+ "top_right_x": 1.8252907,
+ "top_right_y": 1.8252907,
+ "bottom_right_x": 3.6505814,
+ "bottom_right_y": 3.6505814,
+ "bottom_left_x": 3.6505814,
+ "bottom_left_y": 3.6505814
+ },
+ {
+ "top_left_x": 1.4077549,
+ "top_left_y": 1.4077549,
+ "top_right_x": 1.4077549,
+ "top_right_y": 1.4077549,
+ "bottom_right_x": 2.8155098,
+ "bottom_right_y": 2.8155098,
+ "bottom_left_x": 2.8155098,
+ "bottom_left_y": 2.8155098
+ },
+ {
+ "top_left_x": 1.1067667,
+ "top_left_y": 1.1067667,
+ "top_right_x": 1.1067667,
+ "top_right_y": 1.1067667,
+ "bottom_right_x": 2.2135334,
+ "bottom_right_y": 2.2135334,
+ "bottom_left_x": 2.2135334,
+ "bottom_left_y": 2.2135334
+ },
+ {
+ "top_left_x": 0.88593864,
+ "top_left_y": 0.88593864,
+ "top_right_x": 0.88593864,
+ "top_right_y": 0.88593864,
+ "bottom_right_x": 1.7718773,
+ "bottom_right_y": 1.7718773,
+ "bottom_left_x": 1.7718773,
+ "bottom_left_y": 1.7718773
+ },
+ {
+ "top_left_x": 0.7069988,
+ "top_left_y": 0.7069988,
+ "top_right_x": 0.7069988,
+ "top_right_y": 0.7069988,
+ "bottom_right_x": 1.4139977,
+ "bottom_right_y": 1.4139977,
+ "bottom_left_x": 1.4139977,
+ "bottom_left_y": 1.4139977
+ },
+ {
+ "top_left_x": 0.55613136,
+ "top_left_y": 0.55613136,
+ "top_right_x": 0.55613136,
+ "top_right_y": 0.55613136,
+ "bottom_right_x": 1.1122627,
+ "bottom_right_y": 1.1122627,
+ "bottom_left_x": 1.1122627,
+ "bottom_left_y": 1.1122627
+ },
+ {
+ "top_left_x": 0.44889355,
+ "top_left_y": 0.44889355,
+ "top_right_x": 0.44889355,
+ "top_right_y": 0.44889355,
+ "bottom_right_x": 0.8977871,
+ "bottom_right_y": 0.8977871,
+ "bottom_left_x": 0.8977871,
+ "bottom_left_y": 0.8977871
+ },
+ {
+ "top_left_x": 0.34557533,
+ "top_left_y": 0.34557533,
+ "top_right_x": 0.34557533,
+ "top_right_y": 0.34557533,
+ "bottom_right_x": 0.69115067,
+ "bottom_right_y": 0.69115067,
+ "bottom_left_x": 0.69115067,
+ "bottom_left_y": 0.69115067
+ },
+ {
+ "top_left_x": 0.27671337,
+ "top_left_y": 0.27671337,
+ "top_right_x": 0.27671337,
+ "top_right_y": 0.27671337,
+ "bottom_right_x": 0.55342674,
+ "bottom_right_y": 0.55342674,
+ "bottom_left_x": 0.55342674,
+ "bottom_left_y": 0.55342674
+ },
+ {
+ "top_left_x": 0.20785141,
+ "top_left_y": 0.20785141,
+ "top_right_x": 0.20785141,
+ "top_right_y": 0.20785141,
+ "bottom_right_x": 0.41570282,
+ "bottom_right_y": 0.41570282,
+ "bottom_left_x": 0.41570282,
+ "bottom_left_y": 0.41570282
+ },
+ {
+ "top_left_x": 0.1601448,
+ "top_left_y": 0.1601448,
+ "top_right_x": 0.1601448,
+ "top_right_y": 0.1601448,
+ "bottom_right_x": 0.3202896,
+ "bottom_right_y": 0.3202896,
+ "bottom_left_x": 0.3202896,
+ "bottom_left_y": 0.3202896
+ },
+ {
+ "top_left_x": 0.117860794,
+ "top_left_y": 0.117860794,
+ "top_right_x": 0.117860794,
+ "top_right_y": 0.117860794,
+ "bottom_right_x": 0.23572159,
+ "bottom_right_y": 0.23572159,
+ "bottom_left_x": 0.23572159,
+ "bottom_left_y": 0.23572159
+ },
+ {
+ "top_left_x": 0.08036041,
+ "top_left_y": 0.08036041,
+ "top_right_x": 0.08036041,
+ "top_right_y": 0.08036041,
+ "bottom_right_x": 0.16072083,
+ "bottom_right_y": 0.16072083,
+ "bottom_left_x": 0.16072083,
+ "bottom_left_y": 0.16072083
+ },
+ {
+ "top_left_x": 0.05836296,
+ "top_left_y": 0.05836296,
+ "top_right_x": 0.05836296,
+ "top_right_y": 0.05836296,
+ "bottom_right_x": 0.11672592,
+ "bottom_right_y": 0.11672592,
+ "bottom_left_x": 0.11672592,
+ "bottom_left_y": 0.11672592
+ },
+ {
+ "top_left_x": 0.03636551,
+ "top_left_y": 0.03636551,
+ "top_right_x": 0.03636551,
+ "top_right_y": 0.03636551,
+ "bottom_right_x": 0.07273102,
+ "bottom_right_y": 0.07273102,
+ "bottom_left_x": 0.07273102,
+ "bottom_left_y": 0.07273102
+ },
+ {
+ "top_left_x": 0.018137932,
+ "top_left_y": 0.018137932,
+ "top_right_x": 0.018137932,
+ "top_right_y": 0.018137932,
+ "bottom_right_x": 0.036275864,
+ "bottom_right_y": 0.036275864,
+ "bottom_left_x": 0.036275864,
+ "bottom_left_y": 0.036275864
+ },
+ {
+ "top_left_x": 0.0082063675,
+ "top_left_y": 0.0082063675,
+ "top_right_x": 0.0082063675,
+ "top_right_y": 0.0082063675,
+ "bottom_right_x": 0.016412735,
+ "bottom_right_y": 0.016412735,
+ "bottom_left_x": 0.016412735,
+ "bottom_left_y": 0.016412735
+ },
+ {
+ "top_left_x": 0.0031013489,
+ "top_left_y": 0.0031013489,
+ "top_right_x": 0.0031013489,
+ "top_right_y": 0.0031013489,
+ "bottom_right_x": 0.0062026978,
+ "bottom_right_y": 0.0062026978,
+ "bottom_left_x": 0.0062026978,
+ "bottom_left_y": 0.0062026978
+ },
+ {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "top_right_x": 0,
+ "top_right_y": 0,
+ "bottom_right_x": 0,
+ "bottom_right_y": 0,
+ "bottom_left_x": 0,
+ "bottom_left_y": 0
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 233,
+ 191,
+ 153,
+ 117,
+ 85,
+ 57,
+ 33,
+ 14,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
new file mode 100644
index 000000000000..848c7d460d3b
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/animations/withoutFade_withoutHole_whenReturning_withSpring_backgroundAnimationTimeSeries_drawHoleAfterFadeout.json
@@ -0,0 +1,375 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304
+ ],
+ "features": [
+ {
+ "name": "bounds",
+ "type": "rect",
+ "data_points": [
+ {
+ "left": 0,
+ "top": 0,
+ "right": 0,
+ "bottom": 0
+ },
+ {
+ "left": 104,
+ "top": 285,
+ "right": 215,
+ "bottom": 414
+ },
+ {
+ "left": 92,
+ "top": 252,
+ "right": 227,
+ "bottom": 447
+ },
+ {
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
+ },
+ {
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
+ },
+ {
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
+ },
+ {
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
+ },
+ {
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
+ },
+ {
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
+ },
+ {
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
+ },
+ {
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
+ },
+ {
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
+ },
+ {
+ "left": 7,
+ "top": 24,
+ "right": 312,
+ "bottom": 673
+ },
+ {
+ "left": 5,
+ "top": 18,
+ "right": 314,
+ "bottom": 678
+ },
+ {
+ "left": 4,
+ "top": 13,
+ "right": 315,
+ "bottom": 681
+ },
+ {
+ "left": 3,
+ "top": 10,
+ "right": 316,
+ "bottom": 684
+ },
+ {
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
+ "left": 1,
+ "top": 4,
+ "right": 318,
+ "bottom": 688
+ },
+ {
+ "left": 0,
+ "top": 3,
+ "right": 319,
+ "bottom": 688
+ }
+ ]
+ },
+ {
+ "name": "corner_radii",
+ "type": "cornerRadii",
+ "data_points": [
+ null,
+ {
+ "top_left_x": 9.492916,
+ "top_left_y": 9.492916,
+ "top_right_x": 9.492916,
+ "top_right_y": 9.492916,
+ "bottom_right_x": 18.985832,
+ "bottom_right_y": 18.985832,
+ "bottom_left_x": 18.985832,
+ "bottom_left_y": 18.985832
+ },
+ {
+ "top_left_x": 8.381761,
+ "top_left_y": 8.381761,
+ "top_right_x": 8.381761,
+ "top_right_y": 8.381761,
+ "bottom_right_x": 16.763521,
+ "bottom_right_y": 16.763521,
+ "bottom_left_x": 16.763521,
+ "bottom_left_y": 16.763521
+ },
+ {
+ "top_left_x": 7.07397,
+ "top_left_y": 7.07397,
+ "top_right_x": 7.07397,
+ "top_right_y": 7.07397,
+ "bottom_right_x": 14.14794,
+ "bottom_right_y": 14.14794,
+ "bottom_left_x": 14.14794,
+ "bottom_left_y": 14.14794
+ },
+ {
+ "top_left_x": 5.7880254,
+ "top_left_y": 5.7880254,
+ "top_right_x": 5.7880254,
+ "top_right_y": 5.7880254,
+ "bottom_right_x": 11.576051,
+ "bottom_right_y": 11.576051,
+ "bottom_left_x": 11.576051,
+ "bottom_left_y": 11.576051
+ },
+ {
+ "top_left_x": 4.6295347,
+ "top_left_y": 4.6295347,
+ "top_right_x": 4.6295347,
+ "top_right_y": 4.6295347,
+ "bottom_right_x": 9.259069,
+ "bottom_right_y": 9.259069,
+ "bottom_left_x": 9.259069,
+ "bottom_left_y": 9.259069
+ },
+ {
+ "top_left_x": 3.638935,
+ "top_left_y": 3.638935,
+ "top_right_x": 3.638935,
+ "top_right_y": 3.638935,
+ "bottom_right_x": 7.27787,
+ "bottom_right_y": 7.27787,
+ "bottom_left_x": 7.27787,
+ "bottom_left_y": 7.27787
+ },
+ {
+ "top_left_x": 2.8209057,
+ "top_left_y": 2.8209057,
+ "top_right_x": 2.8209057,
+ "top_right_y": 2.8209057,
+ "bottom_right_x": 5.6418114,
+ "bottom_right_y": 5.6418114,
+ "bottom_left_x": 5.6418114,
+ "bottom_left_y": 5.6418114
+ },
+ {
+ "top_left_x": 2.1620893,
+ "top_left_y": 2.1620893,
+ "top_right_x": 2.1620893,
+ "top_right_y": 2.1620893,
+ "bottom_right_x": 4.3241787,
+ "bottom_right_y": 4.3241787,
+ "bottom_left_x": 4.3241787,
+ "bottom_left_y": 4.3241787
+ },
+ {
+ "top_left_x": 1.6414614,
+ "top_left_y": 1.6414614,
+ "top_right_x": 1.6414614,
+ "top_right_y": 1.6414614,
+ "bottom_right_x": 3.2829227,
+ "bottom_right_y": 3.2829227,
+ "bottom_left_x": 3.2829227,
+ "bottom_left_y": 3.2829227
+ },
+ {
+ "top_left_x": 1.2361269,
+ "top_left_y": 1.2361269,
+ "top_right_x": 1.2361269,
+ "top_right_y": 1.2361269,
+ "bottom_right_x": 2.4722538,
+ "bottom_right_y": 2.4722538,
+ "bottom_left_x": 2.4722538,
+ "bottom_left_y": 2.4722538
+ },
+ {
+ "top_left_x": 0.92435074,
+ "top_left_y": 0.92435074,
+ "top_right_x": 0.92435074,
+ "top_right_y": 0.92435074,
+ "bottom_right_x": 1.8487015,
+ "bottom_right_y": 1.8487015,
+ "bottom_left_x": 1.8487015,
+ "bottom_left_y": 1.8487015
+ },
+ {
+ "top_left_x": 0.68693924,
+ "top_left_y": 0.68693924,
+ "top_right_x": 0.68693924,
+ "top_right_y": 0.68693924,
+ "bottom_right_x": 1.3738785,
+ "bottom_right_y": 1.3738785,
+ "bottom_left_x": 1.3738785,
+ "bottom_left_y": 1.3738785
+ },
+ {
+ "top_left_x": 0.5076904,
+ "top_left_y": 0.5076904,
+ "top_right_x": 0.5076904,
+ "top_right_y": 0.5076904,
+ "bottom_right_x": 1.0153809,
+ "bottom_right_y": 1.0153809,
+ "bottom_left_x": 1.0153809,
+ "bottom_left_y": 1.0153809
+ },
+ {
+ "top_left_x": 0.3733511,
+ "top_left_y": 0.3733511,
+ "top_right_x": 0.3733511,
+ "top_right_y": 0.3733511,
+ "bottom_right_x": 0.7467022,
+ "bottom_right_y": 0.7467022,
+ "bottom_left_x": 0.7467022,
+ "bottom_left_y": 0.7467022
+ },
+ {
+ "top_left_x": 0.27331638,
+ "top_left_y": 0.27331638,
+ "top_right_x": 0.27331638,
+ "top_right_y": 0.27331638,
+ "bottom_right_x": 0.54663277,
+ "bottom_right_y": 0.54663277,
+ "bottom_left_x": 0.54663277,
+ "bottom_left_y": 0.54663277
+ },
+ {
+ "top_left_x": 0.19925308,
+ "top_left_y": 0.19925308,
+ "top_right_x": 0.19925308,
+ "top_right_y": 0.19925308,
+ "bottom_right_x": 0.39850616,
+ "bottom_right_y": 0.39850616,
+ "bottom_left_x": 0.39850616,
+ "bottom_left_y": 0.39850616
+ },
+ {
+ "top_left_x": 0.14470005,
+ "top_left_y": 0.14470005,
+ "top_right_x": 0.14470005,
+ "top_right_y": 0.14470005,
+ "bottom_right_x": 0.2894001,
+ "bottom_right_y": 0.2894001,
+ "bottom_left_x": 0.2894001,
+ "bottom_left_y": 0.2894001
+ },
+ {
+ "top_left_x": 0.10470486,
+ "top_left_y": 0.10470486,
+ "top_right_x": 0.10470486,
+ "top_right_y": 0.10470486,
+ "bottom_right_x": 0.20940971,
+ "bottom_right_y": 0.20940971,
+ "bottom_left_x": 0.20940971,
+ "bottom_left_y": 0.20940971
+ },
+ {
+ "top_left_x": 0.07550812,
+ "top_left_y": 0.07550812,
+ "top_right_x": 0.07550812,
+ "top_right_y": 0.07550812,
+ "bottom_right_x": 0.15101624,
+ "bottom_right_y": 0.15101624,
+ "bottom_left_x": 0.15101624,
+ "bottom_left_y": 0.15101624
+ }
+ ]
+ },
+ {
+ "name": "alpha",
+ "type": "int",
+ "data_points": [
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 249,
+ 226,
+ 192,
+ 153,
+ 112,
+ 72,
+ 34,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
index a1f59c2cc2b5..1268de0f4141 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
@@ -23,11 +23,14 @@ import android.animation.recordMotion
import android.graphics.Color
import android.graphics.PointF
import android.graphics.drawable.GradientDrawable
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.MotionTest
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.activity.EmptyTestActivity
import com.android.systemui.concurrency.fakeExecutor
@@ -45,25 +48,29 @@ import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
import platform.test.screenshot.GoldenPathManager
import platform.test.screenshot.PathConfig
+import platform.test.screenshot.PathElementNoContext
@SmallTest
@MotionTest
@RunWith(ParameterizedAndroidJunit4::class)
class TransitionAnimatorTest(
private val fadeWindowBackgroundLayer: Boolean,
+ private val drawHole: Boolean,
private val isLaunching: Boolean,
private val useSpring: Boolean,
) : SysuiTestCase() {
companion object {
private const val GOLDENS_PATH = "frameworks/base/packages/SystemUI/tests/goldens"
- @get:Parameters(name = "fadeBackground={0}, isLaunching={1}, useSpring={2}")
+ @get:Parameters(name = "fadeBackground={0}, drawHole={1}, isLaunching={2}, useSpring={3}")
@JvmStatic
val parameterValues = buildList {
booleanArrayOf(true, false).forEach { fadeBackground ->
- booleanArrayOf(true, false).forEach { isLaunching ->
- booleanArrayOf(true, false).forEach { useSpring ->
- add(arrayOf(fadeBackground, isLaunching, useSpring))
+ booleanArrayOf(true, false).forEach { drawHole ->
+ booleanArrayOf(true, false).forEach { isLaunching ->
+ booleanArrayOf(true, false).forEach { useSpring ->
+ add(arrayOf(fadeBackground, drawHole, isLaunching, useSpring))
+ }
}
}
}
@@ -71,7 +78,44 @@ class TransitionAnimatorTest(
}
private val kosmos = Kosmos()
- private val pathManager = GoldenPathManager(context, GOLDENS_PATH, pathConfig = PathConfig())
+ private val pathManager =
+ GoldenPathManager(
+ context,
+ GOLDENS_PATH,
+ pathConfig =
+ PathConfig(
+ PathElementNoContext("base", isDir = true) { "animations" },
+ PathElementNoContext("fade", isDir = false) {
+ if (fadeWindowBackgroundLayer) {
+ "withFade"
+ } else {
+ "withoutFade"
+ }
+ },
+ PathElementNoContext("hole", isDir = false) {
+ if (drawHole) {
+ "withHole"
+ } else {
+ "withoutHole"
+ }
+ },
+ PathElementNoContext("direction", isDir = false) {
+ if (isLaunching) {
+ "whenLaunching"
+ } else {
+ "whenReturning"
+ }
+ },
+ PathElementNoContext("mode", isDir = false) {
+ if (useSpring) {
+ "withSpring"
+ } else {
+ "withAnimator"
+ }
+ },
+ ),
+ )
+
private val transitionAnimator =
TransitionAnimator(
kosmos.fakeExecutor,
@@ -80,24 +124,6 @@ class TransitionAnimatorTest(
ActivityTransitionAnimator.SPRING_TIMINGS,
ActivityTransitionAnimator.SPRING_INTERPOLATORS,
)
- private val fade =
- if (fadeWindowBackgroundLayer) {
- "withFade"
- } else {
- "withoutFade"
- }
- private val direction =
- if (isLaunching) {
- "whenLaunching"
- } else {
- "whenReturning"
- }
- private val mode =
- if (useSpring) {
- "withSpring"
- } else {
- "withAnimator"
- }
@get:Rule(order = 1) val activityRule = ActivityScenarioRule(EmptyTestActivity::class.java)
@get:Rule(order = 2) val animatorTestRule = android.animation.AnimatorTestRule(this)
@@ -108,6 +134,7 @@ class TransitionAnimatorTest(
pathManager,
)
+ @DisableFlags(Flags.FLAG_MOVE_TRANSITION_ANIMATION_LAYER)
@Test
fun backgroundAnimationTimeSeries() {
val transitionContainer = createScene()
@@ -118,7 +145,21 @@ class TransitionAnimatorTest(
motionRule
.assertThat(recordedMotion)
- .timeSeriesMatchesGolden("backgroundAnimationTimeSeries_${fade}_${direction}_$mode")
+ .timeSeriesMatchesGolden("backgroundAnimationTimeSeries")
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_TRANSITION_ANIMATION_LAYER)
+ @Test
+ fun backgroundAnimationTimeSeries_drawHoleAfterFadeout() {
+ val transitionContainer = createScene()
+ val backgroundLayer = createBackgroundLayer()
+ val animation = createAnimation(transitionContainer, backgroundLayer)
+
+ val recordedMotion = record(backgroundLayer, animation)
+
+ motionRule
+ .assertThat(recordedMotion)
+ .timeSeriesMatchesGolden("backgroundAnimationTimeSeries_drawHoleAfterFadeout")
}
private fun createScene(): ViewGroup {
@@ -169,6 +210,7 @@ class TransitionAnimatorTest(
endState,
backgroundLayer,
fadeWindowBackgroundLayer,
+ drawHole,
startVelocity = startVelocity,
)
.apply { runOnMainThreadAndWaitForIdleSync { start() } }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
index 7c8822bc11ec..96ef8b690145 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
@@ -18,8 +18,6 @@ package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothDevice
import android.graphics.drawable.Drawable
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import android.util.Pair
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -29,7 +27,6 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.flags.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.google.common.truth.Truth.assertThat
@@ -208,42 +205,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
- fun testSavedFactory_isFilterMatched_bondedAndNotConnected_returnsTrue() {
- `when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
- `when`(cachedDevice.isConnected).thenReturn(false)
-
- assertThat(
- savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
- )
- .isTrue()
- }
-
- @Test
- @DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
- fun testSavedFactory_isFilterMatched_connected_returnsFalse() {
- `when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
- `when`(cachedDevice.isConnected).thenReturn(true)
-
- assertThat(
- savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
- )
- .isFalse()
- }
-
- @Test
- @DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
- fun testSavedFactory_isFilterMatched_notBonded_returnsFalse() {
- `when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_NONE)
-
- assertThat(
- savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
- )
- .isFalse()
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testSavedFactory_isFilterMatched_exclusivelyManaged_returnsFalse() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
@@ -255,7 +216,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testSavedFactory_isFilterMatched_notExclusiveManaged_returnsTrue() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
@@ -269,7 +229,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testSavedFactory_isFilterMatched_notExclusivelyManaged_connected_returnsFalse() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
@@ -283,35 +242,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
- fun testConnectedFactory_isFilterMatched_bondedAndConnected_returnsTrue() {
- `when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(true)
-
- assertThat(
- connectedDeviceItemFactory.isFilterMatched(
- context,
- cachedDevice,
- isOngoingCall = false,
- )
- )
- .isTrue()
- }
-
- @Test
- @DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
- fun testConnectedFactory_isFilterMatched_notConnected_returnsFalse() {
- assertThat(
- connectedDeviceItemFactory.isFilterMatched(
- context,
- cachedDevice,
- isOngoingCall = false,
- )
- )
- .isFalse()
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testConnectedFactory_isFilterMatched_exclusivelyManaged_returnsFalse() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
@@ -327,7 +257,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testConnectedFactory_isFilterMatched_noExclusiveManager_returnsTrue() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
@@ -344,7 +273,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testConnectedFactory_isFilterMatched_notExclusivelyManaged_notConnected_returnsFalse() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index 562481567536..5c893da45b8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -28,7 +28,6 @@ import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBO
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHOWN_EXPANDED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHOWN_MINIMIZED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SWIPE_DISMISSED;
-import static com.android.systemui.flags.Flags.CLIPBOARD_IMAGE_TIMEOUT;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -60,7 +59,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastSender;
-import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.screenshot.TimeoutHandler;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -102,7 +100,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
@Mock
private UiEventLogger mUiEventLogger;
private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
- private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
@Mock
private Animator mAnimator;
@@ -152,8 +149,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
mSampleClipData = new ClipData("Test", new String[]{"text/plain"},
new ClipData.Item("Test Item"));
-
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, true); // turned off for legacy tests
}
/**
@@ -170,13 +165,13 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
getFakeBroadcastDispatcher(),
mBroadcastSender,
mTimeoutHandler,
- mFeatureFlags,
mClipboardUtils,
mExecutor,
mClipboardImageLoader,
mClipboardTransitionExecutor,
mClipboardIndicationProvider,
- mUiEventLogger);
+ mUiEventLogger,
+ new ActionIntentCreator());
verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture());
mCallbacks = mOverlayCallbacksCaptor.getValue();
}
@@ -193,7 +188,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
ClipData clipData = new ClipData("", new String[]{"image/png"},
new ClipData.Item(Uri.parse("")));
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
mOverlayController.setClipData(clipData, "");
@@ -208,7 +202,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
ClipData clipData = new ClipData("", new String[]{"resource/png"},
new ClipData.Item(Uri.parse("")));
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
mOverlayController.setClipData(clipData, "");
@@ -219,7 +212,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
@Test
public void test_setClipData_textData_legacy() {
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
initController();
mOverlayController.setClipData(mSampleClipData, "abc");
@@ -232,7 +224,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
@Test
public void test_setClipData_sensitiveTextData_legacy() {
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
initController();
ClipDescription description = mSampleClipData.getDescription();
@@ -250,7 +241,6 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase {
@Test
public void test_setClipData_repeatedCalls_legacy() {
when(mAnimator.isRunning()).thenReturn(true);
- mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
initController();
mOverlayController.setClipData(mSampleClipData, "");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index e8054c07eac8..8105ae0960ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -283,7 +283,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
() -> mSelectedUserInteractor,
mock(UserTracker.class),
mKosmos.getNotificationShadeWindowModel(),
- mSecureSettings,
mKosmos::getCommunalInteractor,
mKosmos.getShadeLayoutParams());
mFeatureFlags = new FakeFeatureFlags();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index 2001a3ea7ca0..dad08e014c0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -422,25 +422,6 @@ class MediaCarouselControllerTest(flags: FlagsParameterization) : SysuiTestCase(
assertTrue(MediaPlayerData.playerKeys().elementAt(2).isSsMediaRec)
}
- @DisableSceneContainer
- @Test
- fun testOrderWithSmartspace_prioritized_updatingVisibleMediaPlayers() {
- verify(mediaDataManager).addListener(capture(listener))
-
- testPlayerOrdering()
-
- // If smartspace is prioritized
- listener.value.onSmartspaceMediaDataLoaded(
- SMARTSPACE_KEY,
- EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true),
- true,
- )
-
- // Then it should be shown immediately after any actively playing controls
- assertTrue(MediaPlayerData.playerKeys().elementAt(2).isSsMediaRec)
- assertTrue(MediaPlayerData.visiblePlayerKeys().elementAt(2).isSsMediaRec)
- }
-
@Test
fun testOrderWithSmartspace_notPrioritized() {
testPlayerOrdering()
@@ -571,146 +552,6 @@ class MediaCarouselControllerTest(flags: FlagsParameterization) : SysuiTestCase(
verify(logger).logRecommendationRemoved(eq(packageName), eq(instanceId!!))
}
- @DisableSceneContainer
- @Test
- fun testMediaLoaded_ScrollToActivePlayer() {
- verify(mediaDataManager).addListener(capture(listener))
-
- listener.value.onMediaDataLoaded(
- PLAYING_LOCAL,
- null,
- DATA.copy(
- active = true,
- isPlaying = true,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false,
- ),
- )
- listener.value.onMediaDataLoaded(
- PAUSED_LOCAL,
- null,
- DATA.copy(
- active = true,
- isPlaying = false,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false,
- ),
- )
- runAllReady()
- // adding a media recommendation card.
- listener.value.onSmartspaceMediaDataLoaded(
- SMARTSPACE_KEY,
- EMPTY_SMARTSPACE_MEDIA_DATA,
- false,
- )
- mediaCarouselController.shouldScrollToKey = true
- // switching between media players.
- listener.value.onMediaDataLoaded(
- PLAYING_LOCAL,
- PLAYING_LOCAL,
- DATA.copy(
- active = true,
- isPlaying = false,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = true,
- ),
- )
- listener.value.onMediaDataLoaded(
- PAUSED_LOCAL,
- PAUSED_LOCAL,
- DATA.copy(
- active = true,
- isPlaying = true,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false,
- ),
- )
- runAllReady()
-
- assertEquals(
- MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL),
- mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex,
- )
- }
-
- @DisableSceneContainer
- @Test
- fun testMediaLoadedFromRecommendationCard_ScrollToActivePlayer() {
- verify(mediaDataManager).addListener(capture(listener))
-
- listener.value.onSmartspaceMediaDataLoaded(
- SMARTSPACE_KEY,
- EMPTY_SMARTSPACE_MEDIA_DATA.copy(packageName = "PACKAGE_NAME", isActive = true),
- false,
- )
- listener.value.onMediaDataLoaded(
- PLAYING_LOCAL,
- null,
- DATA.copy(
- active = true,
- isPlaying = true,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false,
- ),
- )
- runAllReady()
-
- var playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
- assertEquals(
- playerIndex,
- mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex,
- )
- assertEquals(playerIndex, 0)
-
- // Replaying the same media player one more time.
- // And check that the card stays in its position.
- mediaCarouselController.shouldScrollToKey = true
- listener.value.onMediaDataLoaded(
- PLAYING_LOCAL,
- null,
- DATA.copy(
- active = true,
- isPlaying = true,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false,
- packageName = "PACKAGE_NAME",
- ),
- )
- runAllReady()
- playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
- assertEquals(playerIndex, 0)
- }
-
- @DisableSceneContainer
- @Test
- fun testRecommendationRemovedWhileNotVisible_updateHostVisibility() {
- verify(mediaDataManager).addListener(capture(listener))
-
- var result = false
- mediaCarouselController.updateHostVisibility = { result = true }
-
- whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(true)
- listener.value.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY, false)
-
- assertEquals(true, result)
- }
-
- @DisableSceneContainer
- @Test
- fun testRecommendationRemovedWhileVisible_thenReorders_updateHostVisibility() {
- verify(mediaDataManager).addListener(capture(listener))
-
- var result = false
- mediaCarouselController.updateHostVisibility = { result = true }
-
- whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(false)
- listener.value.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY, false)
- assertEquals(false, result)
-
- visualStabilityCallback.value.onReorderingAllowed()
- assertEquals(true, result)
- }
-
@Test
fun testGetCurrentVisibleMediaContentIntent() {
val clickIntent1 = mock(PendingIntent::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
index 9543032ef5ec..88fcc706f072 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
@@ -19,16 +19,12 @@ package com.android.systemui.media.controls.ui.controller
import android.animation.Animator
import android.animation.AnimatorSet
import android.app.PendingIntent
-import android.app.smartspace.SmartspaceAction
-import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
-import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
-import android.graphics.Matrix
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
@@ -47,7 +43,6 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.provider.Settings
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.testing.TestableLooper
-import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.animation.Interpolator
@@ -59,7 +54,6 @@ import android.widget.TextView
import androidx.constraintlayout.widget.Barrier
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
-import androidx.media.utils.MediaConstants
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
@@ -72,19 +66,15 @@ import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.media.controls.MediaTestUtils
-import com.android.systemui.media.controls.domain.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
-import com.android.systemui.media.controls.shared.model.KEY_SMARTSPACE_APP_NAME
import com.android.systemui.media.controls.shared.model.MediaAction
import com.android.systemui.media.controls.shared.model.MediaButton
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDeviceData
import com.android.systemui.media.controls.shared.model.MediaNotificationAction
-import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.ui.binder.SeekBarObserver
import com.android.systemui.media.controls.ui.view.GutsViewHolder
import com.android.systemui.media.controls.ui.view.MediaViewHolder
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.dialog.MediaOutputDialogManager
@@ -216,32 +206,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
- @Mock private lateinit var recommendationViewHolder: RecommendationViewHolder
- @Mock private lateinit var smartspaceAction: SmartspaceAction
- private lateinit var smartspaceData: SmartspaceMediaData
- @Mock private lateinit var coverContainer1: ViewGroup
- @Mock private lateinit var coverContainer2: ViewGroup
- @Mock private lateinit var coverContainer3: ViewGroup
- @Mock private lateinit var recAppIconItem: CachingIconView
- @Mock private lateinit var recCardTitle: TextView
- @Mock private lateinit var coverItem: ImageView
- @Mock private lateinit var matrix: Matrix
- private lateinit var recTitle1: TextView
- private lateinit var recTitle2: TextView
- private lateinit var recTitle3: TextView
- private lateinit var recSubtitle1: TextView
- private lateinit var recSubtitle2: TextView
- private lateinit var recSubtitle3: TextView
- @Mock private lateinit var recProgressBar1: SeekBar
- @Mock private lateinit var recProgressBar2: SeekBar
- @Mock private lateinit var recProgressBar3: SeekBar
@Mock private lateinit var globalSettings: GlobalSettings
- private val intent =
- Intent().apply {
- putExtras(Bundle().also { it.putString(KEY_SMARTSPACE_APP_NAME, REC_APP_NAME) })
- setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- }
+ private val intent = Intent().apply { setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
private val pendingIntent =
PendingIntent.getActivity(
mContext,
@@ -282,7 +249,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
mediaOutputDialogManager,
mediaCarouselController,
falsingManager,
- clock,
logger,
keyguardStateController,
activityIntentHelper,
@@ -304,27 +270,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
initMediaViewHolderMocks()
initDeviceMediaData(false, DEVICE_NAME)
-
- // Set up recommendation view
- initRecommendationViewHolderMocks()
-
- // Set valid recommendation data
- val extras = Bundle()
- extras.putString(KEY_SMARTSPACE_APP_NAME, REC_APP_NAME)
- val intent =
- Intent().apply {
- putExtras(extras)
- setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- whenever(smartspaceAction.intent).thenReturn(intent)
- whenever(smartspaceAction.extras).thenReturn(extras)
- smartspaceData =
- EMPTY_SMARTSPACE_MEDIA_DATA.copy(
- packageName = PACKAGE,
- instanceId = instanceId,
- recommendations = listOf(smartspaceAction, smartspaceAction, smartspaceAction),
- cardAction = smartspaceAction,
- )
}
private fun initGutsViewHolderMocks() {
@@ -471,49 +416,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
whenever(viewHolder.loadingEffectView).thenReturn(loadingEffectView)
}
- /** Initialize elements for the recommendation view holder */
- private fun initRecommendationViewHolderMocks() {
- recTitle1 = TextView(context)
- recTitle2 = TextView(context)
- recTitle3 = TextView(context)
- recSubtitle1 = TextView(context)
- recSubtitle2 = TextView(context)
- recSubtitle3 = TextView(context)
-
- whenever(recommendationViewHolder.recommendations).thenReturn(view)
- whenever(recommendationViewHolder.mediaAppIcons)
- .thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem))
- whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
- whenever(recommendationViewHolder.mediaCoverItems)
- .thenReturn(listOf(coverItem, coverItem, coverItem))
- whenever(recommendationViewHolder.mediaCoverContainers)
- .thenReturn(listOf(coverContainer1, coverContainer2, coverContainer3))
- whenever(recommendationViewHolder.mediaTitles)
- .thenReturn(listOf(recTitle1, recTitle2, recTitle3))
- whenever(recommendationViewHolder.mediaSubtitles)
- .thenReturn(listOf(recSubtitle1, recSubtitle2, recSubtitle3))
- whenever(recommendationViewHolder.mediaProgressBars)
- .thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
- whenever(coverItem.imageMatrix).thenReturn(matrix)
-
- // set ids for recommendation containers
- whenever(coverContainer1.id).thenReturn(1)
- whenever(coverContainer2.id).thenReturn(2)
- whenever(coverContainer3.id).thenReturn(3)
-
- whenever(recommendationViewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
-
- val actionIcon = Icon.createWithResource(context, R.drawable.ic_android)
- whenever(smartspaceAction.icon).thenReturn(actionIcon)
-
- // Needed for card and item action click
- val mockContext = mock(Context::class.java)
- whenever(view.context).thenReturn(mockContext)
- whenever(coverContainer1.context).thenReturn(mockContext)
- whenever(coverContainer2.context).thenReturn(mockContext)
- whenever(coverContainer3.context).thenReturn(mockContext)
- }
-
@After
fun tearDown() {
session.release()
@@ -1488,169 +1390,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
/* ***** END guts tests for the player ***** */
- /* ***** Guts tests for the recommendations ***** */
-
- @Test
- fun recommendations_longClick_isFalse() {
- whenever(falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)).thenReturn(true)
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(viewHolder.player).onLongClickListener = captor.capture()
-
- captor.value.onLongClick(viewHolder.player)
- verify(mediaViewController, never()).openGuts()
- verify(mediaViewController, never()).closeGuts()
- }
-
- @Test
- fun recommendations_longClickWhenGutsClosed_gutsOpens() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
- whenever(mediaViewController.isGutsVisible).thenReturn(false)
-
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(viewHolder.player).onLongClickListener = captor.capture()
-
- captor.value.onLongClick(viewHolder.player)
- verify(mediaViewController).openGuts()
- verify(logger).logLongPressOpen(anyInt(), eq(PACKAGE), eq(instanceId))
- }
-
- @Test
- fun recommendations_longClickWhenGutsOpen_gutsCloses() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
- whenever(mediaViewController.isGutsVisible).thenReturn(true)
-
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(viewHolder.player).onLongClickListener = captor.capture()
-
- captor.value.onLongClick(viewHolder.player)
- verify(mediaViewController, never()).openGuts()
- verify(mediaViewController).closeGuts(false)
- }
-
- @Test
- fun recommendations_cancelButtonClick_animation() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- cancel.callOnClick()
-
- verify(mediaViewController).closeGuts(false)
- }
-
- @Test
- fun recommendations_settingsButtonClick() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- settings.callOnClick()
- verify(logger).logLongPressSettings(anyInt(), eq(PACKAGE), eq(instanceId))
-
- val captor = ArgumentCaptor.forClass(Intent::class.java)
- verify(activityStarter).startActivity(captor.capture(), eq(true))
-
- assertThat(captor.value.action).isEqualTo(ACTION_MEDIA_CONTROLS_SETTINGS)
- }
-
- @Test
- fun recommendations_dismissButtonClick() {
- val mediaKey = "key for dismissal"
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData.copy(targetId = mediaKey))
-
- assertThat(dismiss.isEnabled).isEqualTo(true)
- dismiss.callOnClick()
- verify(logger).logLongPressDismiss(anyInt(), eq(PACKAGE), eq(instanceId))
- verify(mediaDataManager).dismissSmartspaceRecommendation(eq(mediaKey), anyLong())
- }
-
- @Test
- fun recommendation_gutsOpen_contentDescriptionIsForGuts() {
- whenever(mediaViewController.isGutsVisible).thenReturn(true)
- player.attachRecommendation(recommendationViewHolder)
-
- val gutsTextString = "gutsText"
- whenever(gutsText.text).thenReturn(gutsTextString)
- player.bindRecommendation(smartspaceData)
-
- val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
- verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
- val description = descriptionCaptor.value.toString()
-
- assertThat(description).isEqualTo(gutsTextString)
- }
-
- @Test
- fun recommendation_gutsClosed_contentDescriptionIsForPlayer() {
- whenever(mediaViewController.isGutsVisible).thenReturn(false)
- player.attachRecommendation(recommendationViewHolder)
-
- player.bindRecommendation(smartspaceData)
-
- val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
- verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
- val description = descriptionCaptor.value.toString()
-
- assertThat(description)
- .isEqualTo(context.getString(R.string.controls_media_smartspace_rec_header))
- }
-
- @Test
- fun recommendation_gutsChangesFromOpenToClosed_contentDescriptionUpdated() {
- // Start out open
- whenever(mediaViewController.isGutsVisible).thenReturn(true)
- whenever(gutsText.text).thenReturn("gutsText")
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- // Update to closed by long pressing
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(viewHolder.player).onLongClickListener = captor.capture()
- reset(viewHolder.player)
-
- whenever(mediaViewController.isGutsVisible).thenReturn(false)
- captor.value.onLongClick(viewHolder.player)
-
- // Then content description is now the player content description
- val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
- verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
- val description = descriptionCaptor.value.toString()
-
- assertThat(description)
- .isEqualTo(context.getString(R.string.controls_media_smartspace_rec_header))
- }
-
- @Test
- fun recommendation_gutsChangesFromClosedToOpen_contentDescriptionUpdated() {
- // Start out closed
- whenever(mediaViewController.isGutsVisible).thenReturn(false)
- val gutsTextString = "gutsText"
- whenever(gutsText.text).thenReturn(gutsTextString)
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- // Update to open by long pressing
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(viewHolder.player).onLongClickListener = captor.capture()
- reset(viewHolder.player)
-
- whenever(mediaViewController.isGutsVisible).thenReturn(true)
- captor.value.onLongClick(viewHolder.player)
-
- // Then content description is now the guts content description
- val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
- verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
- val description = descriptionCaptor.value.toString()
-
- assertThat(description).isEqualTo(gutsTextString)
- }
-
- /* ***** END guts tests for the recommendations ***** */
-
@Test
fun actionPlayPauseClick_isLogged() {
val semanticActions =
@@ -1887,578 +1626,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
@Test
- fun recommendation_gutsClosed_longPressOpens() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
- whenever(mediaViewController.isGutsVisible).thenReturn(false)
-
- val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
- verify(recommendationViewHolder.recommendations).setOnLongClickListener(captor.capture())
-
- captor.value.onLongClick(recommendationViewHolder.recommendations)
- verify(mediaViewController).openGuts()
- verify(logger).logLongPressOpen(anyInt(), eq(PACKAGE), eq(instanceId))
- }
-
- @Test
- fun recommendation_settingsButtonClick_isLogged() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- settings.callOnClick()
- verify(logger).logLongPressSettings(anyInt(), eq(PACKAGE), eq(instanceId))
-
- val captor = ArgumentCaptor.forClass(Intent::class.java)
- verify(activityStarter).startActivity(captor.capture(), eq(true))
-
- assertThat(captor.value.action).isEqualTo(ACTION_MEDIA_CONTROLS_SETTINGS)
- }
-
- @Test
- fun recommendation_dismissButton_isLogged() {
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- dismiss.callOnClick()
- verify(logger).logLongPressDismiss(anyInt(), eq(PACKAGE), eq(instanceId))
- }
-
- @Test
- fun recommendation_tapOnCard_isLogged() {
- val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- verify(recommendationViewHolder.recommendations).setOnClickListener(captor.capture())
- captor.value.onClick(recommendationViewHolder.recommendations)
-
- verify(logger).logRecommendationCardTap(eq(PACKAGE), eq(instanceId))
- }
-
- @Test
- fun recommendation_tapOnItem_isLogged() {
- val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(smartspaceData)
-
- verify(coverContainer1).setOnClickListener(captor.capture())
- captor.value.onClick(recommendationViewHolder.recommendations)
-
- verify(logger).logRecommendationItemTap(eq(PACKAGE), eq(instanceId), eq(0))
- }
-
- @Test
- fun bindRecommendation_listHasTooFewRecs_notDisplayed() {
- player.attachRecommendation(recommendationViewHolder)
- val icon =
- Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle2")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.bindRecommendation(data)
-
- assertThat(recTitle1.text).isEqualTo("")
- verify(mediaViewController, never()).refreshState()
- }
-
- @Test
- fun bindRecommendation_listHasTooFewRecsWithIcons_notDisplayed() {
- player.attachRecommendation(recommendationViewHolder)
- val icon =
- Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle2")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "empty icon 1")
- .setSubtitle("subtitle2")
- .setIcon(null)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "empty icon 2")
- .setSubtitle("subtitle2")
- .setIcon(null)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.bindRecommendation(data)
-
- assertThat(recTitle1.text).isEqualTo("")
- verify(mediaViewController, never()).refreshState()
- }
-
- @Test
- fun bindRecommendation_hasTitlesAndSubtitles() {
- player.attachRecommendation(recommendationViewHolder)
-
- val title1 = "Title1"
- val title2 = "Title2"
- val title3 = "Title3"
- val subtitle1 = "Subtitle1"
- val subtitle2 = "Subtitle2"
- val subtitle3 = "Subtitle3"
- val icon =
- Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
-
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", title1)
- .setSubtitle(subtitle1)
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", title2)
- .setSubtitle(subtitle2)
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", title3)
- .setSubtitle(subtitle3)
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
- player.bindRecommendation(data)
-
- assertThat(recTitle1.text).isEqualTo(title1)
- assertThat(recTitle2.text).isEqualTo(title2)
- assertThat(recTitle3.text).isEqualTo(title3)
- assertThat(recSubtitle1.text).isEqualTo(subtitle1)
- assertThat(recSubtitle2.text).isEqualTo(subtitle2)
- assertThat(recSubtitle3.text).isEqualTo(subtitle3)
- }
-
- @Test
- fun bindRecommendation_noTitle_subtitleNotShown() {
- player.attachRecommendation(recommendationViewHolder)
-
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "")
- .setSubtitle("fake subtitle")
- .setIcon(
- Icon.createWithResource(
- context,
- com.android.settingslib.R.drawable.ic_1x_mobiledata,
- )
- )
- .setExtras(Bundle.EMPTY)
- .build()
- )
- )
- player.bindRecommendation(data)
-
- assertThat(recSubtitle1.text).isEqualTo("")
- }
-
- @Test
- fun bindRecommendation_someHaveTitles_allTitleViewsShown() {
- useRealConstraintSets()
- player.attachRecommendation(recommendationViewHolder)
-
- val icon =
- Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "")
- .setSubtitle("fake subtitle")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("fake subtitle")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "")
- .setSubtitle("fake subtitle")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
- player.bindRecommendation(data)
-
- assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
- }
-
- @Test
- fun bindRecommendation_someHaveSubtitles_allSubtitleViewsShown() {
- useRealConstraintSets()
- player.attachRecommendation(recommendationViewHolder)
-
- val icon =
- Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "")
- .setSubtitle("")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle2")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("")
- .setIcon(icon)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
- player.bindRecommendation(data)
-
- assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
- }
-
- @Test
- fun bindRecommendation_noneHaveSubtitles_subtitleViewsGone() {
- useRealConstraintSets()
- player.attachRecommendation(recommendationViewHolder)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("")
- .setIcon(
- Icon.createWithResource(
- context,
- com.android.settingslib.R.drawable.ic_1x_mobiledata,
- )
- )
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("")
- .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("")
- .setIcon(
- Icon.createWithResource(
- context,
- com.android.settingslib.R.drawable.ic_3g_mobiledata,
- )
- )
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.bindRecommendation(data)
-
- assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
- }
-
- @Test
- fun bindRecommendation_noneHaveTitles_titleAndSubtitleViewsGone() {
- useRealConstraintSets()
- player.attachRecommendation(recommendationViewHolder)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "")
- .setSubtitle("subtitle1")
- .setIcon(
- Icon.createWithResource(
- context,
- com.android.settingslib.R.drawable.ic_1x_mobiledata,
- )
- )
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "")
- .setSubtitle("subtitle2")
- .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "")
- .setSubtitle("subtitle3")
- .setIcon(
- Icon.createWithResource(
- context,
- com.android.settingslib.R.drawable.ic_3g_mobiledata,
- )
- )
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.bindRecommendation(data)
-
- assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
- }
-
- @Test
- fun bindRecommendation_setAfterExecutors() {
- val albumArt = getColorIcon(Color.RED)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(data)
- bgExecutor.runAllReady()
- mainExecutor.runAllReady()
-
- verify(recCardTitle).setTextColor(any<Int>())
- verify(recAppIconItem, times(3)).setImageDrawable(any<Drawable>())
- verify(coverItem, times(3)).setImageDrawable(any<Drawable>())
- verify(coverItem, times(3)).imageMatrix = any()
- }
-
- @Test
- fun bindRecommendationWithProgressBars() {
- useRealConstraintSets()
- val albumArt = getColorIcon(Color.RED)
- val bundle =
- Bundle().apply {
- putInt(
- MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
- MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED,
- )
- putDouble(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.5)
- }
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(bundle)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(data)
-
- verify(recProgressBar1).setProgress(50)
- verify(recProgressBar1).visibility = View.VISIBLE
- verify(recProgressBar2).visibility = View.GONE
- verify(recProgressBar3).visibility = View.GONE
- assertThat(recSubtitle1.visibility).isEqualTo(View.GONE)
- assertThat(recSubtitle2.visibility).isEqualTo(View.VISIBLE)
- assertThat(recSubtitle3.visibility).isEqualTo(View.VISIBLE)
- }
-
- @Test
- fun bindRecommendation_carouselNotFitThreeRecs_OrientationPortrait() {
- useRealConstraintSets()
- val albumArt = getColorIcon(Color.RED)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- // set the screen width less than the width of media controls.
- player.context.resources.configuration.screenWidthDp = 350
- player.context.resources.configuration.orientation = Configuration.ORIENTATION_PORTRAIT
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(data)
-
- val res = player.context.resources
- val displayAvailableWidth =
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350f, res.displayMetrics).toInt()
- val recCoverWidth: Int =
- (res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width) +
- res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2)
- val numOfRecs = displayAvailableWidth / recCoverWidth
-
- assertThat(player.numberOfFittedRecommendations).isEqualTo(numOfRecs)
- recommendationViewHolder.mediaCoverContainers.forEachIndexed { index, container ->
- if (index < numOfRecs) {
- assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(collapsedSet.getVisibility(container.id))
- .isEqualTo(ConstraintSet.VISIBLE)
- } else {
- assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
- }
- }
- }
-
- @Test
- fun bindRecommendation_carouselNotFitThreeRecs_OrientationLandscape() {
- useRealConstraintSets()
- val albumArt = getColorIcon(Color.RED)
- val data =
- smartspaceData.copy(
- recommendations =
- listOf(
- SmartspaceAction.Builder("id1", "title1")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("subtitle1")
- .setIcon(albumArt)
- .setExtras(Bundle.EMPTY)
- .build(),
- )
- )
-
- // set the screen width less than the width of media controls.
- // We should have dp width less than 378 to test. In landscape we should have 2x.
- player.context.resources.configuration.screenWidthDp = 700
- player.context.resources.configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
- player.attachRecommendation(recommendationViewHolder)
- player.bindRecommendation(data)
-
- val res = player.context.resources
- val displayAvailableWidth =
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350f, res.displayMetrics).toInt()
- val recCoverWidth: Int =
- (res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width) +
- res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2)
- val numOfRecs = displayAvailableWidth / recCoverWidth
-
- assertThat(player.numberOfFittedRecommendations).isEqualTo(numOfRecs)
- recommendationViewHolder.mediaCoverContainers.forEachIndexed { index, container ->
- if (index < numOfRecs) {
- assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(collapsedSet.getVisibility(container.id))
- .isEqualTo(ConstraintSet.VISIBLE)
- } else {
- assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
- }
- }
- }
-
- @Test
- fun addTwoRecommendationGradients_differentStates() {
- // Setup redArtwork and its color scheme.
- val redArt = getColorIcon(Color.RED)
- val redWallpaperColor = player.getWallpaperColor(redArt)
- val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)
-
- // Setup greenArt and its color scheme.
- val greenArt = getColorIcon(Color.GREEN)
- val greenWallpaperColor = player.getWallpaperColor(greenArt)
- val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)
-
- // Add gradient to both icons.
- val redArtwork = player.addGradientToRecommendationAlbum(redArt, redColorScheme, 10, 10)
- val greenArtwork =
- player.addGradientToRecommendationAlbum(greenArt, greenColorScheme, 10, 10)
-
- // They should have different constant states as they have different gradient color.
- assertThat(redArtwork.getDrawable(1).constantState)
- .isNotEqualTo(greenArtwork.getDrawable(1).constantState)
- }
-
- @Test
fun onButtonClick_playsTouchRipple() {
val semanticActions =
MediaButton(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
index e765b6f77155..760f73c726a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
@@ -42,7 +42,6 @@ import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.media.controls.ui.view.GutsViewHolder
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaViewHolder
-import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.res.R
import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView
@@ -79,7 +78,6 @@ class MediaViewControllerTest : SysuiTestCase() {
private val configurationController =
com.android.systemui.statusbar.phone.ConfigurationControllerImpl(context)
private var player = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
- private var recommendation = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
private val clock = FakeSystemClock()
private lateinit var mainExecutor: FakeExecutor
private lateinit var seekBar: SeekBar
@@ -110,9 +108,6 @@ class MediaViewControllerTest : SysuiTestCase() {
@Mock private lateinit var mockCopiedState: TransitionViewState
@Mock private lateinit var detailWidgetState: WidgetState
@Mock private lateinit var controlWidgetState: WidgetState
- @Mock private lateinit var mediaTitleWidgetState: WidgetState
- @Mock private lateinit var mediaSubTitleWidgetState: WidgetState
- @Mock private lateinit var mediaContainerWidgetState: WidgetState
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
@Mock private lateinit var seekBarData: LiveData<SeekBarViewModel.Progress>
@Mock private lateinit var globalSettings: GlobalSettings
@@ -145,7 +140,7 @@ class MediaViewControllerTest : SysuiTestCase() {
context: Context,
animId: Int,
motionInterpolator: Interpolator?,
- vararg targets: View?
+ vararg targets: View?,
): AnimatorSet {
return mockAnimator
}
@@ -158,7 +153,7 @@ class MediaViewControllerTest : SysuiTestCase() {
fun testOrientationChanged_heightOfPlayerIsUpdated() {
val newConfig = Configuration()
- mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
+ mediaViewController.attach(player)
// Change the height to see the effect of orientation change.
MediaViewHolder.backgroundIds.forEach { id ->
mediaViewController.expandedLayout.getConstraint(id).layout.mHeight = 10
@@ -177,30 +172,8 @@ class MediaViewControllerTest : SysuiTestCase() {
}
@Test
- fun testOrientationChanged_heightOfRecCardIsUpdated() {
- val newConfig = Configuration()
-
- mediaViewController.attach(recommendation, MediaViewController.TYPE.RECOMMENDATION)
- // Change the height to see the effect of orientation change.
- mediaViewController.expandedLayout
- .getConstraint(RecommendationViewHolder.backgroundId)
- .layout
- .mHeight = 10
- newConfig.orientation = ORIENTATION_LANDSCAPE
- configurationController.onConfigurationChanged(newConfig)
-
- assertTrue(
- mediaViewController.expandedLayout
- .getConstraint(RecommendationViewHolder.backgroundId)
- .layout
- .mHeight ==
- context.resources.getDimensionPixelSize(R.dimen.qs_media_session_height_expanded)
- )
- }
-
- @Test
fun testObtainViewState_applySquishFraction_toPlayerTransitionViewState_height() {
- mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
+ mediaViewController.attach(player)
player.measureState =
TransitionViewState().apply {
this.height = 100
@@ -224,29 +197,8 @@ class MediaViewControllerTest : SysuiTestCase() {
}
@Test
- fun testObtainViewState_applySquishFraction_toRecommendationTransitionViewState_height() {
- mediaViewController.attach(recommendation, MediaViewController.TYPE.RECOMMENDATION)
- recommendation.measureState = TransitionViewState().apply { this.height = 100 }
- mediaHostStateHolder.expansion = 1f
- val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
- val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
- mediaHostStateHolder.measurementInput =
- MeasurementInput(widthMeasureSpec, heightMeasureSpec)
-
- // Test no squish
- mediaHostStateHolder.squishFraction = 1f
- assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 100)
- assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
-
- // Test half squish
- mediaHostStateHolder.squishFraction = 0.5f
- assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 50)
- assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
- }
-
- @Test
fun testObtainViewState_expandedMatchesParentHeight() {
- mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
+ mediaViewController.attach(player)
player.measureState =
TransitionViewState().apply {
this.height = 100
@@ -283,7 +235,7 @@ class MediaViewControllerTest : SysuiTestCase() {
.thenReturn(
mutableMapOf(
R.id.media_progress_bar to controlWidgetState,
- R.id.header_artist to detailWidgetState
+ R.id.header_artist to detailWidgetState,
)
)
whenever(mockCopiedState.measureHeight).thenReturn(200)
@@ -311,7 +263,7 @@ class MediaViewControllerTest : SysuiTestCase() {
.thenReturn(
mutableMapOf(
R.id.media_progress_bar to controlWidgetState,
- R.id.header_artist to detailWidgetState
+ R.id.header_artist to detailWidgetState,
)
)
whenever(mockCopiedState.measureHeight).thenReturn(200)
@@ -332,46 +284,6 @@ class MediaViewControllerTest : SysuiTestCase() {
verify(detailWidgetState, never()).alpha = floatThat { it > 0 }
}
- @Test
- fun testSquishViewState_applySquishFraction_toTransitionViewState_alpha_forRecommendation() {
- whenever(mockViewState.copy()).thenReturn(mockCopiedState)
- whenever(mockCopiedState.widgetStates)
- .thenReturn(
- mutableMapOf(
- R.id.media_title to mediaTitleWidgetState,
- R.id.media_subtitle to mediaSubTitleWidgetState,
- R.id.media_cover1_container to mediaContainerWidgetState
- )
- )
- whenever(mockCopiedState.measureHeight).thenReturn(360)
- // media container widgets occupy [20, 300]
- whenever(mediaContainerWidgetState.y).thenReturn(20F)
- whenever(mediaContainerWidgetState.height).thenReturn(280)
- whenever(mediaContainerWidgetState.alpha).thenReturn(1F)
- // media title widgets occupy [320, 330]
- whenever(mediaTitleWidgetState.y).thenReturn(320F)
- whenever(mediaTitleWidgetState.height).thenReturn(10)
- whenever(mediaTitleWidgetState.alpha).thenReturn(1F)
- // media subtitle widgets occupy [340, 350]
- whenever(mediaSubTitleWidgetState.y).thenReturn(340F)
- whenever(mediaSubTitleWidgetState.height).thenReturn(10)
- whenever(mediaSubTitleWidgetState.alpha).thenReturn(1F)
-
- // in current beizer, when the progress reach 0.38, the result will be 0.5
- mediaViewController.squishViewState(mockViewState, 307.6F / 360F)
- verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
- mediaViewController.squishViewState(mockViewState, 320F / 360F)
- verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
- // media title and media subtitle are in same widget group, should be calculate together and
- // have same alpha
- mediaViewController.squishViewState(mockViewState, 353.8F / 360F)
- verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
- verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
- mediaViewController.squishViewState(mockViewState, 360F / 360F)
- verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
- verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
- }
-
@EnableSceneContainer
@Test
fun attachPlayer_seekBarDisabled_seekBarVisibilityIsSetToInvisible() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
index 0a5efb7bb286..2d3f538689b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
@@ -162,8 +162,7 @@ class LauncherProxyServiceTest : SysuiTestCase() {
wakefulnessLifecycle.dispatchFinishedGoingToSleep()
clearInvocations(launcherProxy)
- wakefulnessLifecycle
- .dispatchFinishedWakingUp()
+ wakefulnessLifecycle.dispatchFinishedWakingUp()
verify(launcherProxy)
.onSystemUiStateChanged(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
index 8418598c256b..116a2caa6dda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
@@ -19,9 +19,9 @@ package com.android.systemui.shared.condition
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.shared.condition.Condition.START_EAGERLY
-import com.android.systemui.shared.condition.Condition.START_LAZILY
-import com.android.systemui.shared.condition.Condition.START_WHEN_NEEDED
+import com.android.systemui.shared.condition.Condition.Companion.START_EAGERLY
+import com.android.systemui.shared.condition.Condition.Companion.START_LAZILY
+import com.android.systemui.shared.condition.Condition.Companion.START_WHEN_NEEDED
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -40,7 +40,7 @@ class CombinedConditionTest : SysuiTestCase() {
scope: CoroutineScope,
initialValue: Boolean?,
overriding: Boolean = false,
- @StartStrategy private val startStrategy: Int = START_WHEN_NEEDED,
+ @StartStrategy override val startStrategy: Int = START_WHEN_NEEDED,
) : Condition(scope, initialValue, overriding) {
private var _started = false
val started: Boolean
@@ -54,10 +54,6 @@ class CombinedConditionTest : SysuiTestCase() {
_started = false
}
- override fun getStartStrategy(): Int {
- return startStrategy
- }
-
fun setValue(value: Boolean?) {
value?.also { updateCondition(value) } ?: clearCondition()
}
@@ -75,13 +71,8 @@ class CombinedConditionTest : SysuiTestCase() {
val combinedCondition =
CombinedCondition(
scope = this,
- conditions =
- listOf(
- eagerCondition,
- lazyCondition,
- startWhenNeededCondition,
- ),
- operand = Evaluator.OP_OR
+ conditions = listOf(eagerCondition, lazyCondition, startWhenNeededCondition),
+ operand = Evaluator.OP_OR,
)
val callback = Condition.Callback {}
@@ -124,13 +115,8 @@ class CombinedConditionTest : SysuiTestCase() {
val combinedCondition =
CombinedCondition(
scope = this,
- conditions =
- listOf(
- startWhenNeededCondition,
- lazyCondition,
- eagerCondition,
- ),
- operand = Evaluator.OP_AND
+ conditions = listOf(startWhenNeededCondition, lazyCondition, eagerCondition),
+ operand = Evaluator.OP_AND,
)
val callback = Condition.Callback {}
@@ -175,7 +161,7 @@ class CombinedConditionTest : SysuiTestCase() {
FakeCondition(
scope = this,
initialValue = false,
- startStrategy = START_WHEN_NEEDED
+ startStrategy = START_WHEN_NEEDED,
)
}
.toList()
@@ -214,7 +200,7 @@ class CombinedConditionTest : SysuiTestCase() {
FakeCondition(
scope = this,
initialValue = false,
- startStrategy = START_WHEN_NEEDED
+ startStrategy = START_WHEN_NEEDED,
)
}
.toList()
@@ -262,7 +248,7 @@ class CombinedConditionTest : SysuiTestCase() {
FakeCondition(
scope = this,
initialValue = false,
- startStrategy = START_WHEN_NEEDED
+ startStrategy = START_WHEN_NEEDED,
)
}
.toList()
@@ -300,9 +286,9 @@ class CombinedConditionTest : SysuiTestCase() {
overridingCondition1,
lazyCondition,
startWhenNeededCondition,
- overridingCondition2
+ overridingCondition2,
),
- operand = Evaluator.OP_OR
+ operand = Evaluator.OP_OR,
)
val callback = Condition.Callback {}
@@ -414,11 +400,7 @@ class CombinedConditionTest : SysuiTestCase() {
fun testEmptyConditions() = runSelfCancelingTest {
for (operand in intArrayOf(Evaluator.OP_OR, Evaluator.OP_AND)) {
val combinedCondition =
- CombinedCondition(
- scope = this,
- conditions = emptyList(),
- operand = operand,
- )
+ CombinedCondition(scope = this, conditions = emptyList(), operand = operand)
val callback = Condition.Callback {}
combinedCondition.addCallback(callback)
@@ -435,9 +417,7 @@ class CombinedConditionTest : SysuiTestCase() {
* Executes the given block of execution within the scope of a dedicated [CoroutineScope] which
* is then automatically canceled and cleaned-up.
*/
- private fun runSelfCancelingTest(
- block: suspend CoroutineScope.() -> Unit,
- ) =
+ private fun runSelfCancelingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(IMMEDIATE) {
val scope = CoroutineScope(coroutineContext + Job())
block(scope)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
index 86689cb88569..d0357603665d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt
@@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod
+import com.android.systemui.statusbar.notification.row.shared.IconData
import com.android.systemui.statusbar.notification.row.shared.ImageModel
import com.android.systemui.statusbar.notification.row.shared.ImageModelProvider.ImageSizeClass.SmallSquare
import com.google.common.truth.Truth.assertThat
@@ -38,20 +39,22 @@ class RowImageInflaterTest : SysuiTestCase() {
private val resIcon2 = Icon.createWithResource(context, android.R.drawable.ic_delete)
private val badUriIcon = Icon.createWithContentUri("content://com.test/does_not_exist")
+ private var latestImageModelIndex: ImageModelIndex? = null
+
@Before
fun setUp() {
- rowImageInflater = RowImageInflater.newInstance(null)
+ rowImageInflater = RowImageInflater.newInstance(null, reinflating = false)
}
@Test
fun getNewImageIndex_returnsNullWhenUnused() {
- assertThat(rowImageInflater.getNewImageIndex()).isNull()
+ assertThat(getNewImageIndex()).isNull()
}
@Test
fun getNewImageIndex_returnsEmptyIndexWhenZeroImagesLoaded() {
assertThat(getImageModelsForIcons()).isEmpty()
- val result = rowImageInflater.getNewImageIndex()
+ val result = getNewImageIndex()
assertThat(result).isNotNull()
assertThat(result?.contentsForTesting).isEmpty()
}
@@ -59,7 +62,7 @@ class RowImageInflaterTest : SysuiTestCase() {
@Test
fun getNewImageIndex_returnsSingleImageWhenOneImageLoaded() {
assertThat(getImageModelsForIcons(resIcon1)).hasSize(1)
- val result = rowImageInflater.getNewImageIndex()
+ val result = getNewImageIndex()
assertThat(result).isNotNull()
assertThat(result?.contentsForTesting).hasSize(1)
}
@@ -85,7 +88,7 @@ class RowImageInflaterTest : SysuiTestCase() {
assertThat(providedModels[3].drawable).isNotNull()
// VERIFY the returned index has all 3 entries, 2 of which have drawables
- val indexGen1 = rowImageInflater.getNewImageIndex()
+ val indexGen1 = getNewImageIndex()
assertThat(indexGen1).isNotNull()
assertThat(indexGen1?.contentsForTesting).hasSize(3)
assertThat(indexGen1?.contentsForTesting?.mapNotNull { it.drawable }).hasSize(2)
@@ -96,7 +99,7 @@ class RowImageInflaterTest : SysuiTestCase() {
exampleFirstGeneration()
// THEN start a new generation of the inflation
- rowImageInflater = RowImageInflater.newInstance(rowImageInflater.getNewImageIndex())
+ rowImageInflater = RowImageInflater.newInstance(getNewImageIndex(), reinflating = false)
getNewImageIndex_returnsEmptyIndexWhenZeroImagesLoaded()
}
@@ -104,13 +107,47 @@ class RowImageInflaterTest : SysuiTestCase() {
@Test
fun exampleSecondGeneration_whichLoadsOneImage() {
exampleFirstGeneration()
+ val gen1Index = latestImageModelIndex!!
// THEN start a new generation of the inflation
- rowImageInflater = RowImageInflater.newInstance(rowImageInflater.getNewImageIndex())
+ rowImageInflater = RowImageInflater.newInstance(gen1Index, reinflating = false)
getNewImageIndex_returnsSingleImageWhenOneImageLoaded()
+ val gen2Index = latestImageModelIndex!!
+
+ // VERIFY that the drawable was copied from the previous index
+ val gen1model = gen1Index.findModel(resIcon1)
+ val gen2model = gen2Index.findModel(resIcon1)
+ assertThat(gen2model).isNotSameInstanceAs(gen1model)
+ assertThat(gen2model.drawable).isSameInstanceAs(gen1model.drawable)
}
+ @Test
+ fun exampleSecondGeneration_reinflating_whichLoadsOneImage() {
+ exampleFirstGeneration()
+ val gen1Index = latestImageModelIndex!!
+
+ // THEN start a new generation of the inflation
+ rowImageInflater = RowImageInflater.newInstance(gen1Index, reinflating = true)
+
+ getNewImageIndex_returnsSingleImageWhenOneImageLoaded()
+ val gen2Index = latestImageModelIndex!!
+
+ // VERIFY that the drawable was reloaded rather than copied from the previous index
+ val gen1model = gen1Index.findModel(resIcon1)
+ val gen2model = gen2Index.findModel(resIcon1)
+ assertThat(gen2model).isNotSameInstanceAs(gen1model)
+ assertThat(gen2model.drawable).isNotSameInstanceAs(gen1model.drawable)
+ }
+
+ private fun ImageModelIndex.findModel(icon: Icon): LazyImage =
+ IconData.fromIcon(icon)
+ .let { iconData -> contentsForTesting.find { it.icon == iconData } }
+ .also { assertThat(it).isNotNull() }!!
+
+ private fun getNewImageIndex(): ImageModelIndex? =
+ rowImageInflater.getNewImageIndex().also { latestImageModelIndex = it }
+
private fun getImageModelsForIcons(vararg icons: Icon): List<ImageModel> {
val provider = rowImageInflater.useForContentModel()
return icons.map { icon ->
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractorTest.kt
index df45e2e21052..7946a68a6980 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/domain/interactor/BatteryInteractorTest.kt
@@ -22,6 +22,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.policy.batteryController
import com.android.systemui.statusbar.policy.fake
import com.android.systemui.testKosmos
@@ -32,7 +33,7 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class BatteryInteractorTest : SysuiTestCase() {
- val kosmos = testKosmos()
+ val kosmos = testKosmos().useUnconfinedTestDispatcher()
val Kosmos.underTest by Kosmos.Fixture { batteryInteractor }
@Test
@@ -50,11 +51,61 @@ class BatteryInteractorTest : SysuiTestCase() {
assertThat(latest).isEqualTo(BatteryAttributionModel.Defend)
+ batteryController.fake._isDefender = false
+ batteryController.fake._isPowerSave = true
+
+ assertThat(latest).isEqualTo(BatteryAttributionModel.PowerSave)
+
+ batteryController.fake._isPowerSave = false
+ batteryController.fake._isPluggedIn = true
+
+ assertThat(latest).isEqualTo(BatteryAttributionModel.Charging)
+ }
+
+ @Test
+ fun attributionType_prioritizesPowerSaveOverCharging() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.batteryAttributionType)
+
+ batteryController.fake._isPluggedIn = true
+ batteryController.fake._isDefender = true
+ batteryController.fake._isPowerSave = true
+
+ assertThat(latest).isEqualTo(BatteryAttributionModel.PowerSave)
+ }
+
+ @Test
+ fun attributionType_prioritizesPowerSaveOverDefender() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.batteryAttributionType)
+
+ batteryController.fake._isPluggedIn = true
batteryController.fake._isPowerSave = true
+ batteryController.fake._isDefender = false
assertThat(latest).isEqualTo(BatteryAttributionModel.PowerSave)
+ }
+
+ @Test
+ fun attributionType_prioritizesDefenderOverCharging() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.batteryAttributionType)
batteryController.fake._isPluggedIn = true
+ batteryController.fake._isPowerSave = false
+ batteryController.fake._isDefender = true
+
+ assertThat(latest).isEqualTo(BatteryAttributionModel.Defend)
+ }
+
+ @Test
+ fun attributionType_prioritizesChargingOnly() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.batteryAttributionType)
+
+ batteryController.fake._isPluggedIn = true
+ batteryController.fake._isDefender = false
+ batteryController.fake._isPowerSave = false
assertThat(latest).isEqualTo(BatteryAttributionModel.Charging)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/ui/viewmodel/BatteryViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/ui/viewmodel/BatteryViewModelTest.kt
index 6f4c745e8e7e..d8173486c8a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/ui/viewmodel/BatteryViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/ui/viewmodel/BatteryViewModelTest.kt
@@ -97,4 +97,39 @@ class BatteryViewModelTest : SysuiTestCase() {
assertThat(underTest.glyphList).isEqualTo(listOf(BatteryGlyph.BoltLarge))
}
+
+ @Test
+ fun glyphList_attributionOrdering_prioritizesDefendOverCharging() =
+ kosmos.runTest {
+ fakeSystemSettingsRepository.setInt(Settings.System.SHOW_BATTERY_PERCENT, 0)
+ batteryController.fake._level = 39
+ batteryController.fake._isPluggedIn = true
+ batteryController.fake._isDefender = true
+
+ assertThat(underTest.glyphList).isEqualTo(listOf(BatteryGlyph.DefendLarge))
+ }
+
+ @Test
+ fun glyphList_attributionOrdering_prioritizesPowerSaveOverDefend() =
+ kosmos.runTest {
+ fakeSystemSettingsRepository.setInt(Settings.System.SHOW_BATTERY_PERCENT, 0)
+ batteryController.fake._level = 39
+ batteryController.fake._isPluggedIn = true
+ batteryController.fake._isDefender = true
+ batteryController.fake._isPowerSave = true
+
+ assertThat(underTest.glyphList).isEqualTo(listOf(BatteryGlyph.PlusLarge))
+ }
+
+ @Test
+ fun glyphList_attributionOrdering_prioritizesPowerSaveOverCharging() =
+ kosmos.runTest {
+ fakeSystemSettingsRepository.setInt(Settings.System.SHOW_BATTERY_PERCENT, 0)
+ batteryController.fake._level = 39
+ batteryController.fake._isPluggedIn = true
+ batteryController.fake._isDefender = false
+ batteryController.fake._isPowerSave = true
+
+ assertThat(underTest.glyphList).isEqualTo(listOf(BatteryGlyph.PlusLarge))
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 341bd3a38999..a978ecdb3534 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -33,6 +33,8 @@ import static com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_BAR;
import static com.google.common.truth.Truth.assertThat;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -55,8 +57,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
-
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
@@ -136,7 +136,6 @@ import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
-import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -166,7 +165,6 @@ import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvision
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
import com.android.systemui.util.FakeEventLog;
import com.android.systemui.util.settings.FakeGlobalSettings;
-import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SystemSettings;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.Flags;
@@ -451,7 +449,6 @@ public class BubblesTest extends SysuiTestCase {
() -> mSelectedUserInteractor,
mUserTracker,
mNotificationShadeWindowModel,
- new FakeSettings(),
mKosmos::getCommunalInteractor,
mKosmos.getShadeLayoutParams()
);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
index 6f570a86b19e..cd4b09c5267a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
@@ -21,7 +21,6 @@ import com.android.systemui.biometrics.data.repository.fingerprintPropertyReposi
import com.android.systemui.dump.dumpManager
import com.android.systemui.keyevent.domain.interactor.keyEventInteractor
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
-import com.android.systemui.keyguard.domain.interactor.keyguardBypassInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.util.time.systemClock
@@ -31,8 +30,6 @@ val Kosmos.deviceEntryHapticsInteractor by
DeviceEntryHapticsInteractor(
biometricSettingsRepository = biometricSettingsRepository,
deviceEntryBiometricAuthInteractor = deviceEntryBiometricAuthInteractor,
- deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor,
- keyguardBypassInteractor = keyguardBypassInteractor,
deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
deviceEntrySourceInteractor = deviceEntrySourceInteractor,
fingerprintPropertyRepository = fingerprintPropertyRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index af89403c5397..623989ec5809 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -67,6 +67,7 @@ import com.android.systemui.scene.shared.model.sceneDataSource
import com.android.systemui.scene.ui.view.mockWindowRootViewProvider
import com.android.systemui.settings.brightness.data.repository.brightnessMirrorShowingRepository
import com.android.systemui.settings.displayTracker
+import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.interactor.shadeLayoutParams
@@ -203,5 +204,6 @@ class KosmosJavaAdapter() {
val windowRootViewBlurInteractor by lazy { kosmos.windowRootViewBlurInteractor }
val sysuiState by lazy { kosmos.sysUiState }
val displayTracker by lazy { kosmos.displayTracker }
+ val fakeShadeDisplaysRepository by lazy { kosmos.fakeShadeDisplaysRepository }
val sysUIStateDispatcher by lazy { kosmos.sysUIStateDispatcher }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/log/LogWtfHandlerRule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/log/LogWtfHandlerRule.kt
index e639326bd7a1..0e348c88f058 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/log/LogWtfHandlerRule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/log/LogWtfHandlerRule.kt
@@ -24,21 +24,23 @@ import org.junit.runners.model.Statement
class LogWtfHandlerRule : TestRule {
- private var started = false
- private var handler = ThrowAndFailAtEnd
+ private var failureLogExemptions = mutableListOf<FailureLogExemption>()
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun evaluate() {
- started = true
+ val handler = TerribleFailureTestHandler()
val originalWtfHandler = Log.setWtfHandler(handler)
var failure: Throwable? = null
try {
base.evaluate()
} catch (ex: Throwable) {
- failure = ex.runAndAddSuppressed { handler.onTestFailure(ex) }
+ failure = ex
} finally {
- failure = failure.runAndAddSuppressed { handler.onTestFinished() }
+ failure =
+ runAndAddSuppressed(failure) {
+ handler.onTestFinished(failureLogExemptions)
+ }
Log.setWtfHandler(originalWtfHandler)
}
if (failure != null) {
@@ -48,74 +50,52 @@ class LogWtfHandlerRule : TestRule {
}
}
- fun Throwable?.runAndAddSuppressed(block: () -> Unit): Throwable? {
+ /** Adds a log failure exemption. Exemptions are evaluated at the end of the test. */
+ fun addFailureLogExemption(exemption: FailureLogExemption) {
+ failureLogExemptions.add(exemption)
+ }
+
+ /** Clears and sets exemptions. Exemptions are evaluated at the end of the test. */
+ fun resetFailureLogExemptions(vararg exemptions: FailureLogExemption) {
+ failureLogExemptions = exemptions.toMutableList()
+ }
+
+ private fun runAndAddSuppressed(currentError: Throwable?, block: () -> Unit): Throwable? {
try {
block()
} catch (t: Throwable) {
- if (this == null) {
+ if (currentError == null) {
return t
}
- addSuppressed(t)
+ currentError.addSuppressed(t)
}
- return this
+ return currentError
}
- fun setWtfHandler(handler: TerribleFailureTestHandler) {
- check(!started) { "Should only be called before the test starts" }
- this.handler = handler
- }
-
- fun interface TerribleFailureTestHandler : TerribleFailureHandler {
- fun onTestFailure(failure: Throwable) {}
- fun onTestFinished() {}
- }
-
- companion object Handlers {
- val ThrowAndFailAtEnd
- get() =
- object : TerribleFailureTestHandler {
- val failures = mutableListOf<Log.TerribleFailure>()
-
- override fun onTerribleFailure(
- tag: String,
- what: Log.TerribleFailure,
- system: Boolean
- ) {
- failures.add(what)
- throw what
- }
+ private class TerribleFailureTestHandler : TerribleFailureHandler {
+ private val failureLogs = mutableListOf<FailureLog>()
- override fun onTestFailure(failure: Throwable) {
- super.onTestFailure(failure)
- }
+ override fun onTerribleFailure(tag: String, what: Log.TerribleFailure, system: Boolean) {
+ failureLogs.add(FailureLog(tag = tag, failure = what, system = system))
+ }
- override fun onTestFinished() {
- if (failures.isNotEmpty()) {
- throw AssertionError("Unexpected Log.wtf calls: $failures", failures[0])
- }
- }
+ fun onTestFinished(exemptions: List<FailureLogExemption>) {
+ val failures =
+ failureLogs.filter { failureLog ->
+ !exemptions.any { it.isFailureLogExempt(failureLog) }
}
+ if (failures.isNotEmpty()) {
+ throw AssertionError("Unexpected Log.wtf calls: $failures", failures[0].failure)
+ }
+ }
+ }
- val JustThrow = TerribleFailureTestHandler { _, what, _ -> throw what }
-
- val JustFailAtEnd
- get() =
- object : TerribleFailureTestHandler {
- val failures = mutableListOf<Log.TerribleFailure>()
-
- override fun onTerribleFailure(
- tag: String,
- what: Log.TerribleFailure,
- system: Boolean
- ) {
- failures.add(what)
- }
+ /** All the information from a call to [Log.wtf] that was handed to [TerribleFailureHandler] */
+ data class FailureLog(val tag: String, val failure: Log.TerribleFailure, val system: Boolean)
- override fun onTestFinished() {
- if (failures.isNotEmpty()) {
- throw AssertionError("Unexpected Log.wtf calls: $failures", failures[0])
- }
- }
- }
+ /** An interface for exempting a [FailureLog] from causing a test failure. */
+ fun interface FailureLogExemption {
+ /** Determines whether a log should be except from failing the test. */
+ fun isFailureLogExempt(log: FailureLog): Boolean
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt
deleted file mode 100644
index 1edd405f4af6..000000000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.domain.pipeline.interactor
-
-import android.content.applicationContext
-import com.android.systemui.broadcast.broadcastSender
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.media.controls.data.repository.mediaFilterRepository
-import com.android.systemui.media.controls.domain.pipeline.mediaDataProcessor
-import com.android.systemui.plugins.activityStarter
-
-val Kosmos.mediaRecommendationsInteractor by
- Kosmos.Fixture {
- MediaRecommendationsInteractor(
- applicationScope = applicationCoroutineScope,
- applicationContext = applicationContext,
- repository = mediaFilterRepository,
- mediaDataProcessor = mediaDataProcessor,
- broadcastSender = broadcastSender,
- activityStarter = activityStarter,
- )
- }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
index 5e6434d84538..976b4046f58d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
@@ -37,7 +37,6 @@ val Kosmos.mediaCarouselViewModel by
visualStabilityProvider = visualStabilityProvider,
interactor = mediaCarouselInteractor,
controlInteractorFactory = mediaControlInteractorFactory,
- recommendationsViewModel = mediaRecommendationsViewModel,
logger = mediaUiEventLogger,
mediaLogger = mediaLogger,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt
deleted file mode 100644
index 34a527781979..000000000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.controls.ui.viewmodel
-
-import android.content.applicationContext
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testDispatcher
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
-import com.android.systemui.media.controls.util.mediaUiEventLogger
-
-val Kosmos.mediaRecommendationsViewModel by
- Kosmos.Fixture {
- MediaRecommendationsViewModel(
- applicationContext = applicationContext,
- backgroundDispatcher = testDispatcher,
- interactor = mediaRecommendationsInteractor,
- logger = mediaUiEventLogger,
- )
- }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
index 00deaafd7009..11bd4c7b7940 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.model
import android.view.Display
import com.android.systemui.common.domain.interactor.SysUIStateDisplaysInteractor
import com.android.systemui.display.data.repository.FakePerDisplayRepository
+import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -31,12 +32,7 @@ val Kosmos.sysUiStateFactory by Fixture {
object : SysUiStateImpl.Factory {
override fun create(displayId: Int): SysUiStateImpl {
return spy(
- SysUiStateImpl(
- displayId,
- sceneContainerPlugin,
- dumpManager,
- sysUIStateDispatcher,
- )
+ SysUiStateImpl(displayId, sceneContainerPlugin, dumpManager, sysUIStateDispatcher)
)
}
}
@@ -45,5 +41,17 @@ val Kosmos.sysUiStateFactory by Fixture {
val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture { FakePerDisplayRepository<SysUiState>() }
val Kosmos.sysuiStateInteractor by Fixture {
- SysUIStateDisplaysInteractor(fakeSysUIStatePerDisplayRepository)
+ SysUIStateDisplaysInteractor(fakeSysUIStatePerDisplayRepository, displayRepository)
+}
+
+val Kosmos.sysUiStateOverrideFactory by Fixture {
+ { displayId: Int ->
+ SysUIStateOverride(
+ displayId,
+ sceneContainerPlugin,
+ dumpManager,
+ sysUiState,
+ sysUIStateDispatcher,
+ )
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt
index 7145907a14a8..39391d03a44b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt
@@ -18,14 +18,19 @@ package com.android.systemui.statusbar.featurepods.media.ui.viewmodel
import android.content.testableContext
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.statusbar.featurepods.media.domain.interactor.mediaControlChipInteractor
-val Kosmos.mediaControlChipViewModel: MediaControlChipViewModel by
+private val Kosmos.mediaControlChipViewModel: MediaControlChipViewModel by
Kosmos.Fixture {
MediaControlChipViewModel(
- backgroundScope = applicationCoroutineScope,
applicationContext = testableContext,
mediaControlChipInteractor = mediaControlChipInteractor,
)
}
+
+val Kosmos.mediaControlChipViewModelFactory by
+ Kosmos.Fixture {
+ object : MediaControlChipViewModel.Factory {
+ override fun create(): MediaControlChipViewModel = mediaControlChipViewModel
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
index b876095fefe5..2a3167cb66f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
@@ -17,10 +17,12 @@
package com.android.systemui.statusbar.featurepods.popups.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.mediaControlChipViewModel
+import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.mediaControlChipViewModelFactory
private val Kosmos.statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel by
- Kosmos.Fixture { StatusBarPopupChipsViewModel(mediaControlChip = mediaControlChipViewModel) }
+ Kosmos.Fixture {
+ StatusBarPopupChipsViewModel(mediaControlChipFactory = mediaControlChipViewModelFactory)
+ }
val Kosmos.statusBarPopupChipsViewModelFactory by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt
index c337ac201b3d..8e98fe31a56a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt
@@ -18,6 +18,10 @@ package com.android.systemui.statusbar.notification
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.phone.statusBarNotificationActivityStarter
+import org.mockito.kotlin.mock
var Kosmos.notificationActivityStarter: NotificationActivityStarter by
Kosmos.Fixture { statusBarNotificationActivityStarter }
+
+var Kosmos.mockNotificationActivityStarter: NotificationActivityStarter by
+Kosmos.Fixture { mock<NotificationActivityStarter>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt
new file mode 100644
index 000000000000..f3cdabb5813e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+var Kosmos.groupMembershipManager by Kosmos.Fixture { mock<GroupMembershipManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt
new file mode 100644
index 000000000000..c263c5d96610
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.people
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+val Kosmos.notificationPersonExtractor by Kosmos.Fixture { mock<NotificationPersonExtractor>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt
new file mode 100644
index 000000000000..20982eb43797
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.people
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.collection.render.groupMembershipManager
+
+val Kosmos.peopleNotificationIdentifier by
+ Kosmos.Fixture {
+ PeopleNotificationIdentifierImpl(notificationPersonExtractor, groupMembershipManager)
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
index da879d9e314d..2b3158da38f9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
@@ -39,7 +39,8 @@ fun Kosmos.setPromotedContent(entry: NotificationEntry) {
promotedNotificationContentExtractor.extractContent(
entry,
Notification.Builder.recoverBuilder(applicationContext, entry.sbn.notification),
- RowImageInflater.newInstance(null).useForContentModel(),
+ RowImageInflater.newInstance(previousIndex = null, reinflating = false)
+ .useForContentModel(),
)
entry.promotedNotificationContentModel =
requireNotNull(extractedContent) { "extractContent returned null" }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt
new file mode 100644
index 000000000000..e99f61e7cd13
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import com.android.internal.logging.metricsLogger
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl
+import com.android.systemui.statusbar.notification.collection.coordinator.visualStabilityCoordinator
+import com.android.systemui.statusbar.notification.mockNotificationActivityStarter
+import com.android.systemui.statusbar.notification.people.peopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider
+
+val Kosmos.entryAdapterFactory by
+Kosmos.Fixture {
+ EntryAdapterFactoryImpl(
+ mockNotificationActivityStarter,
+ metricsLogger,
+ peopleNotificationIdentifier,
+ notificationIconStyleProvider,
+ visualStabilityCoordinator,
+ )
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
index 771e1a5dccc3..ff4fbf9f0e94 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -53,8 +53,11 @@ import com.android.systemui.statusbar.SmartReplyController
import com.android.systemui.statusbar.notification.ColorUpdateLogger
import com.android.systemui.statusbar.notification.ConversationNotificationManager
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
+import com.android.systemui.statusbar.notification.NotificationActivityStarter
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider
@@ -76,6 +79,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
import com.android.systemui.statusbar.notification.row.icon.AppIconProviderImpl
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderImpl
import com.android.systemui.statusbar.notification.row.icon.NotificationRowIconViewInflaterFactory
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
@@ -364,11 +368,22 @@ class ExpandableNotificationRowBuilder(
)
val row = rowInflaterTask.inflateSynchronously(context, null, entry)
+ val entryAdapter =
+ EntryAdapterFactoryImpl(
+ Mockito.mock(NotificationActivityStarter::class.java),
+ Mockito.mock(MetricsLogger::class.java),
+ Mockito.mock(PeopleNotificationIdentifier::class.java),
+ Mockito.mock(NotificationIconStyleProvider::class.java),
+ Mockito.mock(VisualStabilityCoordinator::class.java),
+ )
+ .create(entry)
+
entry.row = row
mIconManager.createIcons(entry)
mBindPipelineEntryListener.onEntryInit(entry)
mBindPipeline.manageRow(entry, row)
row.initialize(
+ entryAdapter,
entry,
Mockito.mock(RemoteInputViewSubcomponent.Factory::class.java, STUB_ONLY),
APP_NAME,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index a97c651ba426..5c4deaadffd5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -25,6 +25,7 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.log.table.tableLogBufferFactory
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.shade.domain.interactor.shadeDisplaysInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
@@ -40,29 +41,34 @@ import com.android.systemui.statusbar.pipeline.shared.domain.interactor.homeStat
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.homeStatusBarInteractor
var Kosmos.homeStatusBarViewModel: HomeStatusBarViewModel by
+ Kosmos.Fixture { homeStatusBarViewModelFactory.invoke(testableContext.displayId) }
+var Kosmos.homeStatusBarViewModelFactory: (Int) -> HomeStatusBarViewModel by
Kosmos.Fixture {
- HomeStatusBarViewModelImpl(
- testableContext.displayId,
- batteryViewModelFactory,
- tableLogBufferFactory,
- homeStatusBarInteractor,
- homeStatusBarIconBlockListInteractor,
- lightsOutInteractor,
- activeNotificationsInteractor,
- darkIconInteractor,
- headsUpNotificationInteractor,
- keyguardTransitionInteractor,
- keyguardInteractor,
- statusBarOperatorNameViewModel,
- sceneInteractor,
- sceneContainerOcclusionInteractor,
- shadeInteractor,
- shareToAppChipViewModel,
- ongoingActivityChipsViewModel,
- statusBarPopupChipsViewModelFactory,
- systemStatusEventAnimationInteractor,
- multiDisplayStatusBarContentInsetsViewModelStore,
- backgroundScope,
- testDispatcher,
- )
+ { displayId ->
+ HomeStatusBarViewModelImpl(
+ displayId,
+ batteryViewModelFactory,
+ tableLogBufferFactory,
+ homeStatusBarInteractor,
+ homeStatusBarIconBlockListInteractor,
+ lightsOutInteractor,
+ activeNotificationsInteractor,
+ darkIconInteractor,
+ headsUpNotificationInteractor,
+ keyguardTransitionInteractor,
+ keyguardInteractor,
+ statusBarOperatorNameViewModel,
+ sceneInteractor,
+ sceneContainerOcclusionInteractor,
+ shadeInteractor,
+ shareToAppChipViewModel,
+ ongoingActivityChipsViewModel,
+ statusBarPopupChipsViewModelFactory,
+ systemStatusEventAnimationInteractor,
+ multiDisplayStatusBarContentInsetsViewModelStore,
+ backgroundScope,
+ testDispatcher,
+ { shadeDisplaysInteractor },
+ )
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponentKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponentKosmos.kt
index 4ca044d60f3f..34218646b818 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponentKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponentKosmos.kt
@@ -33,6 +33,8 @@ import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSlide
import com.android.systemui.volume.dialog.sliders.domain.model.volumeDialogSliderType
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogOverscrollViewBinder
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.volumeDialogSliderViewModel
import com.android.systemui.volume.dialog.sliders.ui.volumeDialogOverscrollViewBinder
import com.android.systemui.volume.dialog.sliders.ui.volumeDialogSliderViewBinder
import com.android.systemui.volume.mediaControllerRepository
@@ -60,6 +62,9 @@ fun Kosmos.volumeDialogSliderComponent(type: VolumeDialogSliderType): VolumeDial
}
}
+ override fun sliderViewModel(): VolumeDialogSliderViewModel =
+ localKosmos.volumeDialogSliderViewModel
+
override fun sliderViewBinder(): VolumeDialogSliderViewBinder =
localKosmos.volumeDialogSliderViewBinder
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
index 97574e6e35e3..aad534c3289c 100644
--- a/packages/Vcn/service-b/Android.bp
+++ b/packages/Vcn/service-b/Android.bp
@@ -29,7 +29,10 @@ filegroup {
"vcn-location-flag/platform/com/android/server/vcn/VcnLocation.java",
],
}),
- visibility: ["//frameworks/base/services/core"],
+ visibility: [
+ "//frameworks/base/services/core",
+ "//packages/modules/Connectivity/service-t",
+ ],
}
// TODO: b/374174952 This library is only used in "service-connectivity-b-platform"
diff --git a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
index b9dcc6160d68..aac217b3cc7a 100644
--- a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
+++ b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
@@ -37,9 +37,27 @@ public final class ConnectivityServiceInitializerB extends SystemService {
private static final String TAG = ConnectivityServiceInitializerB.class.getSimpleName();
private final VcnManagementService mVcnManagementService;
+ // STOPSHIP: b/385203616 This static flag is for handling a temporary case when the mainline
+ // module prebuilt has updated to register the VCN but the platform change to remove
+ // registration is not merged. After mainline prebuilt is updated, we should merge the platform
+ // ASAP and remove this static check. This check is safe because both mainline and platform
+ // registration are triggered from the same method on the same thread.
+ private static boolean sIsRegistered = false;
+
public ConnectivityServiceInitializerB(Context context) {
super(context);
- mVcnManagementService = VcnManagementService.create(context);
+
+ if (!sIsRegistered) {
+ mVcnManagementService = VcnManagementService.create(context);
+ sIsRegistered = true;
+ } else {
+ mVcnManagementService = null;
+ Log.e(
+ TAG,
+ "Ignore this registration since VCN is already registered. It will happen when"
+ + " the mainline module prebuilt has updated to register the VCN but the"
+ + " platform change to remove registration is not merged.");
+ }
}
@Override
diff --git a/ravenwood/scripts/list-ravenwood-tests.sh b/ravenwood/scripts/list-ravenwood-tests.sh
index 05f3fdffdaa7..5d7daeb1c304 100755
--- a/ravenwood/scripts/list-ravenwood-tests.sh
+++ b/ravenwood/scripts/list-ravenwood-tests.sh
@@ -15,4 +15,20 @@
# List all the ravenwood test modules.
-jq -r 'to_entries[] | select( .value.compatibility_suites | index("ravenwood-tests") ) | .key' "$OUT/module-info.json" | sort
+set -e
+
+in="$OUT/module-info.json"
+cache="$OUT/ravenwood-test-list.cached.tmp"
+cache_temp="$OUT/ravenwood-test-list.temp.tmp"
+
+if [[ "$in" -nt "$cache" ]] ; then
+ rm -f "$cache_temp" "$cache"
+
+ # First, create to a temp file, and once it's completed, rename it
+ # to the actual cache file, so that if the command failed or is interrupted,
+ # we don't update the cache.
+ jq -r 'to_entries[] | select( .value.compatibility_suites | index("ravenwood-tests") ) | .key' "$OUT/module-info.json" | sort > "$cache_temp"
+ mv "$cache_temp" "$cache"
+fi
+
+cat "$cache"
diff --git a/ravenwood/tools/hoststubgen/Android.bp b/ravenwood/tools/hoststubgen/Android.bp
index a5ff4964b0a4..004834eed983 100644
--- a/ravenwood/tools/hoststubgen/Android.bp
+++ b/ravenwood/tools/hoststubgen/Android.bp
@@ -90,11 +90,9 @@ java_library {
java_library_host {
name: "hoststubgen-lib",
defaults: ["ravenwood-internal-only-visibility-java"],
- srcs: ["src/**/*.kt"],
+ srcs: ["lib/**/*.kt"],
static_libs: [
"hoststubgen-helper-runtime",
- ],
- libs: [
"junit",
"ow2-asm",
"ow2-asm-analysis",
@@ -108,15 +106,8 @@ java_library_host {
java_binary_host {
name: "hoststubgen",
main_class: "com.android.hoststubgen.HostStubGenMain",
- static_libs: [
- "hoststubgen-lib",
- "junit",
- "ow2-asm",
- "ow2-asm-analysis",
- "ow2-asm-commons",
- "ow2-asm-tree",
- "ow2-asm-util",
- ],
+ srcs: ["src/**/*.kt"],
+ static_libs: ["hoststubgen-lib"],
visibility: ["//visibility:public"],
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Exceptions.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Exceptions.kt
index f59e143c1e4e..f59e143c1e4e 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Exceptions.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Exceptions.kt
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessor.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessor.kt
new file mode 100644
index 000000000000..4fe21eac6972
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessor.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hoststubgen
+
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.filters.AnnotationBasedFilter
+import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
+import com.android.hoststubgen.filters.ConstantFilter
+import com.android.hoststubgen.filters.DefaultHookInjectingFilter
+import com.android.hoststubgen.filters.FilterRemapper
+import com.android.hoststubgen.filters.ImplicitOutputFilter
+import com.android.hoststubgen.filters.KeepNativeFilter
+import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.filters.SanitizationFilter
+import com.android.hoststubgen.filters.TextFileFilterPolicyBuilder
+import com.android.hoststubgen.utils.ClassPredicate
+import com.android.hoststubgen.visitors.BaseAdapter
+import com.android.hoststubgen.visitors.PackageRedirectRemapper
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.ClassWriter
+import org.objectweb.asm.commons.ClassRemapper
+import org.objectweb.asm.util.CheckClassAdapter
+
+/**
+ * This class implements bytecode transformation of HostStubGen.
+ */
+class HostStubGenClassProcessor(
+ private val options: HostStubGenClassProcessorOptions,
+ private val allClasses: ClassNodes,
+ private val errors: HostStubGenErrors = HostStubGenErrors(),
+ private val stats: HostStubGenStats? = null,
+) {
+ val filter = buildFilter()
+ val remapper = FilterRemapper(filter)
+
+ private val packageRedirector = PackageRedirectRemapper(options.packageRedirects)
+
+ /**
+ * Build the filter, which decides what classes/methods/fields should be put in stub or impl
+ * jars, and "how". (e.g. with substitution?)
+ */
+ private fun buildFilter(): OutputFilter {
+ // We build a "chain" of multiple filters here.
+ //
+ // The filters are build in from "inside", meaning the first filter created here is
+ // the last filter used, so it has the least precedence.
+ //
+ // So, for example, the "remove" annotation, which is handled by AnnotationBasedFilter,
+ // can override a class-wide annotation, which is handled by
+ // ClassWidePolicyPropagatingFilter, and any annotations can be overridden by the
+ // text-file based filter, which is handled by parseTextFilterPolicyFile.
+
+ // The first filter is for the default policy from the command line options.
+ var filter: OutputFilter = ConstantFilter(options.defaultPolicy.get, "default-by-options")
+
+ // Next, we build a filter that preserves all native methods by default
+ filter = KeepNativeFilter(allClasses, filter)
+
+ // Next, we need a filter that resolves "class-wide" policies.
+ // This is used when a member (methods, fields, nested classes) don't get any policies
+ // from upper filters. e.g. when a method has no annotations, then this filter will apply
+ // the class-wide policy, if any. (if not, we'll fall back to the above filter.)
+ filter = ClassWidePolicyPropagatingFilter(allClasses, filter)
+
+ // Inject default hooks from options.
+ filter = DefaultHookInjectingFilter(
+ allClasses,
+ options.defaultClassLoadHook.get,
+ options.defaultMethodCallHook.get,
+ filter
+ )
+
+ val annotationAllowedPredicate = options.annotationAllowedClassesFile.get.let { file ->
+ if (file == null) {
+ ClassPredicate.newConstantPredicate(true) // Allow all classes
+ } else {
+ ClassPredicate.loadFromFile(file, false)
+ }
+ }
+
+ // Next, Java annotation based filter.
+ val annotFilter = AnnotationBasedFilter(
+ errors,
+ allClasses,
+ options.keepAnnotations,
+ options.keepClassAnnotations,
+ options.throwAnnotations,
+ options.removeAnnotations,
+ options.ignoreAnnotations,
+ options.substituteAnnotations,
+ options.redirectAnnotations,
+ options.redirectionClassAnnotations,
+ options.classLoadHookAnnotations,
+ options.partiallyAllowedAnnotations,
+ options.keepStaticInitializerAnnotations,
+ annotationAllowedPredicate,
+ filter
+ )
+ filter = annotFilter
+
+ // Next, "text based" filter, which allows to override policies without touching
+ // the target code.
+ if (options.policyOverrideFiles.isNotEmpty()) {
+ val builder = TextFileFilterPolicyBuilder(allClasses, filter)
+ options.policyOverrideFiles.forEach(builder::parse)
+ filter = builder.createOutputFilter()
+ annotFilter.annotationAllowedMembers = builder.annotationAllowedMembersFilter
+ }
+
+ // Apply the implicit filter.
+ filter = ImplicitOutputFilter(errors, allClasses, filter)
+
+ // Add a final sanitization step.
+ filter = SanitizationFilter(errors, allClasses, filter)
+
+ return filter
+ }
+
+ fun processClassBytecode(bytecode: ByteArray): ByteArray {
+ val cr = ClassReader(bytecode)
+
+ // COMPUTE_FRAMES wouldn't be happy if code uses
+ val flags = ClassWriter.COMPUTE_MAXS // or ClassWriter.COMPUTE_FRAMES
+ val cw = ClassWriter(flags)
+
+ // Connect to the class writer
+ var outVisitor: ClassVisitor = cw
+ if (options.enableClassChecker.get) {
+ outVisitor = CheckClassAdapter(outVisitor)
+ }
+
+ // Remapping should happen at the end.
+ outVisitor = ClassRemapper(outVisitor, remapper)
+
+ val visitorOptions = BaseAdapter.Options(
+ errors = errors,
+ stats = stats,
+ enablePreTrace = options.enablePreTrace.get,
+ enablePostTrace = options.enablePostTrace.get,
+ deleteClassFinals = options.deleteFinals.get,
+ deleteMethodFinals = options.deleteFinals.get,
+ )
+ outVisitor = BaseAdapter.getVisitor(
+ cr.className, allClasses, outVisitor, filter,
+ packageRedirector, visitorOptions
+ )
+
+ cr.accept(outVisitor, ClassReader.EXPAND_FRAMES)
+ return cw.toByteArray()
+ }
+}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessorOptions.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessorOptions.kt
new file mode 100644
index 000000000000..c7c45e65a8b6
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenClassProcessorOptions.kt
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hoststubgen
+
+import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.utils.ArgIterator
+import com.android.hoststubgen.utils.BaseOptions
+import com.android.hoststubgen.utils.SetOnce
+
+private fun parsePackageRedirect(fromColonTo: String): Pair<String, String> {
+ val colon = fromColonTo.indexOf(':')
+ if ((colon < 1) || (colon + 1 >= fromColonTo.length)) {
+ throw ArgumentsException("--package-redirect must be a colon-separated string")
+ }
+ // TODO check for duplicates
+ return Pair(fromColonTo.substring(0, colon), fromColonTo.substring(colon + 1))
+}
+
+/**
+ * Options to configure [HostStubGenClassProcessor].
+ */
+open class HostStubGenClassProcessorOptions(
+ var keepAnnotations: MutableSet<String> = mutableSetOf(),
+ var throwAnnotations: MutableSet<String> = mutableSetOf(),
+ var removeAnnotations: MutableSet<String> = mutableSetOf(),
+ var ignoreAnnotations: MutableSet<String> = mutableSetOf(),
+ var keepClassAnnotations: MutableSet<String> = mutableSetOf(),
+ var partiallyAllowedAnnotations: MutableSet<String> = mutableSetOf(),
+ var redirectAnnotations: MutableSet<String> = mutableSetOf(),
+
+ var substituteAnnotations: MutableSet<String> = mutableSetOf(),
+ var redirectionClassAnnotations: MutableSet<String> = mutableSetOf(),
+ var classLoadHookAnnotations: MutableSet<String> = mutableSetOf(),
+ var keepStaticInitializerAnnotations: MutableSet<String> = mutableSetOf(),
+
+ var packageRedirects: MutableList<Pair<String, String>> = mutableListOf(),
+
+ var annotationAllowedClassesFile: SetOnce<String?> = SetOnce(null),
+
+ var defaultClassLoadHook: SetOnce<String?> = SetOnce(null),
+ var defaultMethodCallHook: SetOnce<String?> = SetOnce(null),
+
+ var policyOverrideFiles: MutableList<String> = mutableListOf(),
+
+ var defaultPolicy: SetOnce<FilterPolicy> = SetOnce(FilterPolicy.Remove),
+
+ var deleteFinals: SetOnce<Boolean> = SetOnce(false),
+
+ var enableClassChecker: SetOnce<Boolean> = SetOnce(false),
+ var enablePreTrace: SetOnce<Boolean> = SetOnce(false),
+ var enablePostTrace: SetOnce<Boolean> = SetOnce(false),
+) : BaseOptions() {
+
+ private val allAnnotations = mutableSetOf<String>()
+
+ private fun ensureUniqueAnnotation(name: String): String {
+ if (!allAnnotations.add(name)) {
+ throw DuplicateAnnotationException(name)
+ }
+ return name
+ }
+
+ override fun parseOption(option: String, ai: ArgIterator): Boolean {
+ // Define some shorthands...
+ fun nextArg(): String = ai.nextArgRequired(option)
+ fun MutableSet<String>.addUniqueAnnotationArg(): String =
+ nextArg().also { this += ensureUniqueAnnotation(it) }
+
+ when (option) {
+ "--policy-override-file" ->
+ policyOverrideFiles.add(nextArg().ensureFileExists())
+
+ "--default-remove" -> defaultPolicy.set(FilterPolicy.Remove)
+ "--default-throw" -> defaultPolicy.set(FilterPolicy.Throw)
+ "--default-keep" -> defaultPolicy.set(FilterPolicy.Keep)
+
+ "--keep-annotation" ->
+ keepAnnotations.addUniqueAnnotationArg()
+
+ "--keep-class-annotation" ->
+ keepClassAnnotations.addUniqueAnnotationArg()
+
+ "--partially-allowed-annotation" ->
+ partiallyAllowedAnnotations.addUniqueAnnotationArg()
+
+ "--throw-annotation" ->
+ throwAnnotations.addUniqueAnnotationArg()
+
+ "--remove-annotation" ->
+ removeAnnotations.addUniqueAnnotationArg()
+
+ "--ignore-annotation" ->
+ ignoreAnnotations.addUniqueAnnotationArg()
+
+ "--substitute-annotation" ->
+ substituteAnnotations.addUniqueAnnotationArg()
+
+ "--redirect-annotation" ->
+ redirectAnnotations.addUniqueAnnotationArg()
+
+ "--redirection-class-annotation" ->
+ redirectionClassAnnotations.addUniqueAnnotationArg()
+
+ "--class-load-hook-annotation" ->
+ classLoadHookAnnotations.addUniqueAnnotationArg()
+
+ "--keep-static-initializer-annotation" ->
+ keepStaticInitializerAnnotations.addUniqueAnnotationArg()
+
+ "--package-redirect" ->
+ packageRedirects += parsePackageRedirect(nextArg())
+
+ "--annotation-allowed-classes-file" ->
+ annotationAllowedClassesFile.set(nextArg())
+
+ "--default-class-load-hook" ->
+ defaultClassLoadHook.set(nextArg())
+
+ "--default-method-call-hook" ->
+ defaultMethodCallHook.set(nextArg())
+
+ "--delete-finals" -> deleteFinals.set(true)
+
+ // Following options are for debugging.
+ "--enable-class-checker" -> enableClassChecker.set(true)
+ "--no-class-checker" -> enableClassChecker.set(false)
+
+ "--enable-pre-trace" -> enablePreTrace.set(true)
+ "--no-pre-trace" -> enablePreTrace.set(false)
+
+ "--enable-post-trace" -> enablePostTrace.set(true)
+ "--no-post-trace" -> enablePostTrace.set(false)
+
+ else -> return false
+ }
+
+ return true
+ }
+
+ override fun dumpFields(): String {
+ return """
+ keepAnnotations=$keepAnnotations,
+ throwAnnotations=$throwAnnotations,
+ removeAnnotations=$removeAnnotations,
+ ignoreAnnotations=$ignoreAnnotations,
+ keepClassAnnotations=$keepClassAnnotations,
+ partiallyAllowedAnnotations=$partiallyAllowedAnnotations,
+ substituteAnnotations=$substituteAnnotations,
+ nativeSubstituteAnnotations=$redirectionClassAnnotations,
+ classLoadHookAnnotations=$classLoadHookAnnotations,
+ keepStaticInitializerAnnotations=$keepStaticInitializerAnnotations,
+ packageRedirects=$packageRedirects,
+ annotationAllowedClassesFile=$annotationAllowedClassesFile,
+ defaultClassLoadHook=$defaultClassLoadHook,
+ defaultMethodCallHook=$defaultMethodCallHook,
+ policyOverrideFiles=${policyOverrideFiles.toTypedArray().contentToString()},
+ defaultPolicy=$defaultPolicy,
+ deleteFinals=$deleteFinals,
+ enableClassChecker=$enableClassChecker,
+ enablePreTrace=$enablePreTrace,
+ enablePostTrace=$enablePostTrace,
+ """.trimIndent()
+ }
+}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenErrors.kt
index a218c5599553..a218c5599553 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenErrors.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenLogger.kt
index 4bcee409aaec..4bcee409aaec 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenLogger.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenStats.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
index 9045db210495..9045db210495 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenStats.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Utils.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
index 10179eefcb95..b2af7827f8c5 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/Utils.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
@@ -15,6 +15,8 @@
*/
package com.android.hoststubgen
+import java.io.PrintWriter
+
/**
* Name of this executable. Set it in the main method.
*/
@@ -96,3 +98,23 @@ class ParseException : Exception, UserErrorException {
fun csvEscape(value: String): String {
return "\"" + value.replace("\"", "\"\"") + "\""
}
+
+inline fun runMainWithBoilerplate(realMain: () -> Unit) {
+ var success = false
+
+ try {
+ realMain()
+
+ success = true
+ } catch (e: Throwable) {
+ log.e("$executableName: Error: ${e.message}")
+ if (e !is UserErrorException) {
+ e.printStackTrace(PrintWriter(log.getWriter(LogLevel.Error)))
+ }
+ } finally {
+ log.i("$executableName finished")
+ log.flush()
+ }
+
+ System.exit(if (success) 0 else 1 )
+}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/AsmUtils.kt
index b41ce0f65017..b41ce0f65017 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/AsmUtils.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
index e2647eb13ed3..e2647eb13ed3 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/dumper/ApiDumper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
index 5e4e70f0cbaa..5e4e70f0cbaa 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/dumper/ApiDumper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
index 6b360b79c327..b2252092f923 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
@@ -66,7 +66,7 @@ private fun ClassNodes.isFeatureFlagsClass(className: String): Boolean {
|| className.endsWith("/FeatureFlags")
|| className.endsWith("/FeatureFlagsImpl")
|| className.endsWith("/CustomFeatureFlags")
- || className.endsWith("/FakeFeatureFlagsImpl");
+ || className.endsWith("/FakeFeatureFlagsImpl")
}
/**
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
index 73c72a21ef7b..73c72a21ef7b 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt
index f8bb526d0a86..f8bb526d0a86 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ConstantFilter.kt
index be3c59c80152..be3c59c80152 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ConstantFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
index aaf49c154a17..aaf49c154a17 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DelegatingFilter.kt
index b8b0d8a31268..b8b0d8a31268 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/DelegatingFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
index 81c26ffdf1f4..81c26ffdf1f4 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
index b10165b835f2..b10165b835f2 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterRemapper.kt
index bba4681d3838..bba4681d3838 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterRemapper.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
index 474da6dfa1b9..474da6dfa1b9 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
index fc885d6f463b..fc885d6f463b 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/KeepNativeFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
index 00e7d77fa6e7..00e7d77fa6e7 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/KeepNativeFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/OutputFilter.kt
index f99ce906240a..f99ce906240a 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/OutputFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/PackageFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/PackageFilter.kt
index c67e6714d4c2..c67e6714d4c2 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/PackageFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/PackageFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SanitizationFilter.kt
index 4375c6500b62..4375c6500b62 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SanitizationFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SubclassFilter.kt
index fd7474b55fa6..fd7474b55fa6 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/SubclassFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
index dd353e9caeff..dd353e9caeff 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
index a3f934cacc2c..a3f934cacc2c 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
index bc90d1248322..bc90d1248322 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/ClassPredicate.kt
index 4c53bc8fba97..4c53bc8fba97 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/ClassPredicate.kt
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/OptionUtils.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/OptionUtils.kt
new file mode 100644
index 000000000000..0b17879b862c
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/OptionUtils.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hoststubgen.utils
+
+import com.android.hoststubgen.ArgumentsException
+import com.android.hoststubgen.ensureFileExists
+import com.android.hoststubgen.log
+import com.android.hoststubgen.normalizeTextLine
+import java.io.BufferedReader
+import java.io.FileReader
+
+/**
+ * Base class for parsing arguments from commandline.
+ */
+abstract class BaseOptions {
+ /**
+ * Parse all arguments.
+ *
+ * This method should remain final. For customization in subclasses, override [parseOption].
+ */
+ fun parseArgs(args: List<String>) {
+ val ai = ArgIterator.withAtFiles(args)
+ while (true) {
+ val arg = ai.nextArgOptional() ?: break
+
+ if (log.maybeHandleCommandLineArg(arg) { ai.nextArgRequired(arg) }) {
+ continue
+ }
+ try {
+ if (!parseOption(arg, ai)) {
+ throw ArgumentsException("Unknown option: $arg")
+ }
+ } catch (e: SetOnce.SetMoreThanOnceException) {
+ throw ArgumentsException("Duplicate or conflicting argument found: $arg")
+ }
+ }
+
+ checkArgs()
+ }
+
+ /**
+ * Print out all fields in this class.
+ *
+ * This method should remain final. For customization in subclasses, override [dumpFields].
+ */
+ final override fun toString(): String {
+ val fields = dumpFields().prependIndent(" ")
+ return "${this::class.simpleName} {\n$fields\n}"
+ }
+
+ /**
+ * Check whether the parsed options are in a correct state.
+ *
+ * This method is called as the last step in [parseArgs].
+ */
+ open fun checkArgs() {}
+
+ /**
+ * Parse a single option. Return true if the option is accepted, otherwise return false.
+ *
+ * Subclasses override/extend this method to support more options.
+ */
+ abstract fun parseOption(option: String, ai: ArgIterator): Boolean
+
+ abstract fun dumpFields(): String
+}
+
+class ArgIterator(
+ private val args: List<String>,
+ private var currentIndex: Int = -1
+) {
+ val current: String
+ get() = args[currentIndex]
+
+ /**
+ * Get the next argument, or [null] if there's no more arguments.
+ */
+ fun nextArgOptional(): String? {
+ if ((currentIndex + 1) >= args.size) {
+ return null
+ }
+ return args[++currentIndex]
+ }
+
+ /**
+ * Get the next argument, or throw if
+ */
+ fun nextArgRequired(argName: String): String {
+ nextArgOptional().let {
+ if (it == null) {
+ throw ArgumentsException("Missing parameter for option $argName")
+ }
+ if (it.isEmpty()) {
+ throw ArgumentsException("Parameter can't be empty for option $argName")
+ }
+ return it
+ }
+ }
+
+ companion object {
+ fun withAtFiles(args: List<String>): ArgIterator {
+ return ArgIterator(expandAtFiles(args))
+ }
+
+ /**
+ * Scan the arguments, and if any of them starts with an `@`, then load from the file
+ * and use its content as arguments.
+ *
+ * In order to pass an argument that starts with an '@', use '@@' instead.
+ *
+ * In this file, each line is treated as a single argument.
+ *
+ * The file can contain '#' as comments.
+ */
+ private fun expandAtFiles(args: List<String>): List<String> {
+ val ret = mutableListOf<String>()
+
+ args.forEach { arg ->
+ if (arg.startsWith("@@")) {
+ ret += arg.substring(1)
+ return@forEach
+ } else if (!arg.startsWith('@')) {
+ ret += arg
+ return@forEach
+ }
+ // Read from the file, and add each line to the result.
+ val filename = arg.substring(1).ensureFileExists()
+
+ log.v("Expanding options file $filename")
+
+ BufferedReader(FileReader(filename)).use { reader ->
+ while (true) {
+ var line = reader.readLine() ?: break // EOF
+
+ line = normalizeTextLine(line)
+ if (line.isNotEmpty()) {
+ ret += line
+ }
+ }
+ }
+ }
+ return ret
+ }
+ }
+}
+
+/**
+ * A single value that can only set once.
+ */
+open class SetOnce<T>(private var value: T) {
+ class SetMoreThanOnceException : Exception()
+
+ private var set = false
+
+ fun set(v: T): T {
+ if (set) {
+ throw SetMoreThanOnceException()
+ }
+ if (v == null) {
+ throw NullPointerException("This shouldn't happen")
+ }
+ set = true
+ value = v
+ return v
+ }
+
+ val get: T
+ get() = this.value
+
+ val isSet: Boolean
+ get() = this.set
+
+ fun <R> ifSet(block: (T & Any) -> R): R? {
+ if (isSet) {
+ return block(value!!)
+ }
+ return null
+ }
+
+ override fun toString(): String {
+ return "$value"
+ }
+}
+
+class IntSetOnce(value: Int) : SetOnce<Int>(value) {
+ fun set(v: String): Int {
+ try {
+ return this.set(v.toInt())
+ } catch (e: NumberFormatException) {
+ throw ArgumentsException("Invalid integer $v")
+ }
+ }
+}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/Trie.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/Trie.kt
index 1b3d79cddb8e..1b3d79cddb8e 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/Trie.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/utils/Trie.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BaseAdapter.kt
index a08d1d605949..a08d1d605949 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BaseAdapter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt
index 55d0c0e555f1..55d0c0e555f1 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/Helper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/Helper.kt
index dc4f26bdda34..dc4f26bdda34 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/Helper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/Helper.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
index b8a357668c2b..b8a357668c2b 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt
index e90ecd7ef678..e90ecd7ef678 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 7e294ed652d3..333540573364 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -17,36 +17,15 @@ package com.android.hoststubgen
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.dumper.ApiDumper
-import com.android.hoststubgen.filters.AnnotationBasedFilter
-import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
-import com.android.hoststubgen.filters.ConstantFilter
-import com.android.hoststubgen.filters.DefaultHookInjectingFilter
import com.android.hoststubgen.filters.FilterPolicy
-import com.android.hoststubgen.filters.FilterRemapper
-import com.android.hoststubgen.filters.ImplicitOutputFilter
-import com.android.hoststubgen.filters.KeepNativeFilter
-import com.android.hoststubgen.filters.OutputFilter
-import com.android.hoststubgen.filters.SanitizationFilter
-import com.android.hoststubgen.filters.TextFileFilterPolicyBuilder
import com.android.hoststubgen.filters.printAsTextPolicy
-import com.android.hoststubgen.utils.ClassPredicate
-import com.android.hoststubgen.visitors.BaseAdapter
-import com.android.hoststubgen.visitors.PackageRedirectRemapper
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.FileOutputStream
-import java.io.InputStream
-import java.io.OutputStream
import java.io.PrintWriter
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
-import org.objectweb.asm.ClassReader
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.ClassWriter
-import org.objectweb.asm.commons.ClassRemapper
-import org.objectweb.asm.commons.Remapper
-import org.objectweb.asm.util.CheckClassAdapter
/**
* Actual main class.
@@ -76,21 +55,15 @@ class HostStubGen(val options: HostStubGenOptions) {
}
}
- // Build the filters.
- val filter = buildFilter(errors, allClasses, options)
-
- val filterRemapper = FilterRemapper(filter)
+ // Build the class processor
+ val processor = HostStubGenClassProcessor(options, allClasses, errors, stats)
// Transform the jar.
convert(
options.inJar.get,
options.outJar.get,
- filter,
+ processor,
options.enableClassChecker.get,
- allClasses,
- errors,
- stats,
- filterRemapper,
options.numShards.get,
options.shard.get,
)
@@ -106,109 +79,20 @@ class HostStubGen(val options: HostStubGenOptions) {
PrintWriter(it).use { pw ->
// TODO, when dumping a jar that's not framework-minus-apex.jar, we need to feed
// framework-minus-apex.jar so that we can dump inherited methods from it.
- ApiDumper(pw, allClasses, null, filter).dump()
+ ApiDumper(pw, allClasses, null, processor.filter).dump()
}
}
}
}
/**
- * Build the filter, which decides what classes/methods/fields should be put in stub or impl
- * jars, and "how". (e.g. with substitution?)
- */
- private fun buildFilter(
- errors: HostStubGenErrors,
- allClasses: ClassNodes,
- options: HostStubGenOptions,
- ): OutputFilter {
- // We build a "chain" of multiple filters here.
- //
- // The filters are build in from "inside", meaning the first filter created here is
- // the last filter used, so it has the least precedence.
- //
- // So, for example, the "remove" annotation, which is handled by AnnotationBasedFilter,
- // can override a class-wide annotation, which is handled by
- // ClassWidePolicyPropagatingFilter, and any annotations can be overridden by the
- // text-file based filter, which is handled by parseTextFilterPolicyFile.
-
- // The first filter is for the default policy from the command line options.
- var filter: OutputFilter = ConstantFilter(options.defaultPolicy.get, "default-by-options")
-
- // Next, we build a filter that preserves all native methods by default
- filter = KeepNativeFilter(allClasses, filter)
-
- // Next, we need a filter that resolves "class-wide" policies.
- // This is used when a member (methods, fields, nested classes) don't get any polices
- // from upper filters. e.g. when a method has no annotations, then this filter will apply
- // the class-wide policy, if any. (if not, we'll fall back to the above filter.)
- filter = ClassWidePolicyPropagatingFilter(allClasses, filter)
-
- // Inject default hooks from options.
- filter = DefaultHookInjectingFilter(
- allClasses,
- options.defaultClassLoadHook.get,
- options.defaultMethodCallHook.get,
- filter
- )
-
- val annotationAllowedPredicate = options.annotationAllowedClassesFile.get.let { file ->
- if (file == null) {
- ClassPredicate.newConstantPredicate(true) // Allow all classes
- } else {
- ClassPredicate.loadFromFile(file, false)
- }
- }
-
- // Next, Java annotation based filter.
- val annotFilter = AnnotationBasedFilter(
- errors,
- allClasses,
- options.keepAnnotations,
- options.keepClassAnnotations,
- options.throwAnnotations,
- options.removeAnnotations,
- options.ignoreAnnotations,
- options.substituteAnnotations,
- options.redirectAnnotations,
- options.redirectionClassAnnotations,
- options.classLoadHookAnnotations,
- options.partiallyAllowedAnnotations,
- options.keepStaticInitializerAnnotations,
- annotationAllowedPredicate,
- filter
- )
- filter = annotFilter
-
- // Next, "text based" filter, which allows to override polices without touching
- // the target code.
- if (options.policyOverrideFiles.isNotEmpty()) {
- val builder = TextFileFilterPolicyBuilder(allClasses, filter)
- options.policyOverrideFiles.forEach(builder::parse)
- filter = builder.createOutputFilter()
- annotFilter.annotationAllowedMembers = builder.annotationAllowedMembersFilter
- }
-
- // Apply the implicit filter.
- filter = ImplicitOutputFilter(errors, allClasses, filter)
-
- // Add a final sanitization step.
- filter = SanitizationFilter(errors, allClasses, filter)
-
- return filter
- }
-
- /**
* Convert a JAR file into "stub" and "impl" JAR files.
*/
private fun convert(
inJar: String,
outJar: String?,
- filter: OutputFilter,
+ processor: HostStubGenClassProcessor,
enableChecker: Boolean,
- classes: ClassNodes,
- errors: HostStubGenErrors,
- stats: HostStubGenStats,
- remapper: Remapper?,
numShards: Int,
shard: Int
) {
@@ -216,8 +100,6 @@ class HostStubGen(val options: HostStubGenOptions) {
log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")
log.iTime("Transforming jar") {
- val packageRedirector = PackageRedirectRemapper(options.packageRedirects)
-
var itemIndex = 0
var numItemsProcessed = 0
var numItems = -1 // == Unknown
@@ -240,11 +122,7 @@ class HostStubGen(val options: HostStubGenOptions) {
if (!inShard) {
continue
}
- convertSingleEntry(
- inZip, entry, outStream, filter,
- packageRedirector, remapper, enableChecker,
- classes, errors, stats
- )
+ convertSingleEntry(inZip, entry, outStream, processor)
numItemsProcessed++
}
log.i("Converted all entries.")
@@ -270,13 +148,7 @@ class HostStubGen(val options: HostStubGenOptions) {
inZip: ZipFile,
entry: ZipEntry,
outStream: ZipOutputStream?,
- filter: OutputFilter,
- packageRedirector: PackageRedirectRemapper,
- remapper: Remapper?,
- enableChecker: Boolean,
- classes: ClassNodes,
- errors: HostStubGenErrors,
- stats: HostStubGenStats
+ processor: HostStubGenClassProcessor
) {
log.d("Entry: %s", entry.name)
log.withIndent {
@@ -289,10 +161,7 @@ class HostStubGen(val options: HostStubGenOptions) {
// If it's a class, convert it.
if (name.endsWith(".class")) {
- processSingleClass(
- inZip, entry, outStream, filter, packageRedirector,
- remapper, enableChecker, classes, errors, stats
- )
+ processSingleClass(inZip, entry, outStream, processor)
return
}
@@ -332,29 +201,23 @@ class HostStubGen(val options: HostStubGenOptions) {
}
/**
- * Convert a single class to "stub" and "impl".
+ * Convert a single class.
*/
private fun processSingleClass(
inZip: ZipFile,
entry: ZipEntry,
outStream: ZipOutputStream?,
- filter: OutputFilter,
- packageRedirector: PackageRedirectRemapper,
- remapper: Remapper?,
- enableChecker: Boolean,
- classes: ClassNodes,
- errors: HostStubGenErrors,
- stats: HostStubGenStats
+ processor: HostStubGenClassProcessor
) {
val classInternalName = entry.name.replaceFirst("\\.class$".toRegex(), "")
- val classPolicy = filter.getPolicyForClass(classInternalName)
+ val classPolicy = processor.filter.getPolicyForClass(classInternalName)
if (classPolicy.policy == FilterPolicy.Remove) {
log.d("Removing class: %s %s", classInternalName, classPolicy)
return
}
// If we're applying a remapper, we need to rename the file too.
var newName = entry.name
- remapper?.mapType(classInternalName)?.let { remappedName ->
+ processor.remapper.mapType(classInternalName)?.let { remappedName ->
if (remappedName != classInternalName) {
log.d("Renaming class file: %s -> %s", classInternalName, remappedName)
newName = "$remappedName.class"
@@ -367,64 +230,11 @@ class HostStubGen(val options: HostStubGenOptions) {
BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
val newEntry = ZipEntry(newName)
outStream.putNextEntry(newEntry)
- convertClass(
- classInternalName, bis,
- outStream, filter, packageRedirector, remapper,
- enableChecker, classes, errors, stats
- )
+ val classBytecode = bis.readAllBytes()
+ outStream.write(processor.processClassBytecode(classBytecode))
outStream.closeEntry()
}
}
}
}
-
- /**
- * Convert a single class to either "stub" or "impl".
- */
- private fun convertClass(
- classInternalName: String,
- input: InputStream,
- out: OutputStream,
- filter: OutputFilter,
- packageRedirector: PackageRedirectRemapper,
- remapper: Remapper?,
- enableChecker: Boolean,
- classes: ClassNodes,
- errors: HostStubGenErrors,
- stats: HostStubGenStats?
- ) {
- val cr = ClassReader(input)
-
- // COMPUTE_FRAMES wouldn't be happy if code uses
- val flags = ClassWriter.COMPUTE_MAXS // or ClassWriter.COMPUTE_FRAMES
- val cw = ClassWriter(flags)
-
- // Connect to the class writer
- var outVisitor: ClassVisitor = cw
- if (enableChecker) {
- outVisitor = CheckClassAdapter(outVisitor)
- }
-
- // Remapping should happen at the end.
- remapper?.let {
- outVisitor = ClassRemapper(outVisitor, remapper)
- }
-
- val visitorOptions = BaseAdapter.Options(
- errors = errors,
- stats = stats,
- enablePreTrace = options.enablePreTrace.get,
- enablePostTrace = options.enablePostTrace.get,
- deleteClassFinals = options.deleteFinals.get,
- deleteMethodFinals = options.deleteFinals.get,
- )
- outVisitor = BaseAdapter.getVisitor(
- classInternalName, classes, outVisitor, filter,
- packageRedirector, visitorOptions
- )
-
- cr.accept(outVisitor, ClassReader.EXPAND_FRAMES)
- val data = cw.toByteArray()
- out.write(data)
- }
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenMain.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenMain.kt
index 85064661cd2b..4ba8c5c50059 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenMain.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenMain.kt
@@ -17,8 +17,6 @@
package com.android.hoststubgen
-import java.io.PrintWriter
-
/**
* Entry point.
*/
@@ -26,10 +24,10 @@ fun main(args: Array<String>) {
executableName = "HostStubGen"
runMainWithBoilerplate {
// Parse the command line arguments.
- var clanupOnError = false
+ var cleanupOnError = false
try {
- val options = HostStubGenOptions.parseArgs(args)
- clanupOnError = options.cleanUpOnError.get
+ val options = HostStubGenOptions().apply { parseArgs(args.asList()) }
+ cleanupOnError = options.cleanUpOnError.get
log.v("$executableName started")
log.v("Options: $options")
@@ -37,30 +35,10 @@ fun main(args: Array<String>) {
// Run.
HostStubGen(options).run()
} catch (e: Throwable) {
- if (clanupOnError) {
+ if (cleanupOnError) {
TODO("Remove output jars here")
}
throw e
}
}
}
-
-inline fun runMainWithBoilerplate(realMain: () -> Unit) {
- var success = false
-
- try {
- realMain()
-
- success = true
- } catch (e: Throwable) {
- log.e("$executableName: Error: ${e.message}")
- if (e !is UserErrorException) {
- e.printStackTrace(PrintWriter(log.getWriter(LogLevel.Error)))
- }
- } finally {
- log.i("$executableName finished")
- log.flush()
- }
-
- System.exit(if (success) 0 else 1 )
-}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
index 1ab88d24ab28..8bb454fa12e7 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -15,385 +15,102 @@
*/
package com.android.hoststubgen
-import com.android.hoststubgen.filters.FilterPolicy
-import java.io.BufferedReader
-import java.io.FileReader
-
-/**
- * A single value that can only set once.
- */
-open class SetOnce<T>(private var value: T) {
- class SetMoreThanOnceException : Exception()
-
- private var set = false
-
- fun set(v: T): T {
- if (set) {
- throw SetMoreThanOnceException()
- }
- if (v == null) {
- throw NullPointerException("This shouldn't happen")
- }
- set = true
- value = v
- return v
- }
-
- val get: T
- get() = this.value
-
- val isSet: Boolean
- get() = this.set
-
- fun <R> ifSet(block: (T & Any) -> R): R? {
- if (isSet) {
- return block(value!!)
- }
- return null
- }
-
- override fun toString(): String {
- return "$value"
- }
-}
-
-class IntSetOnce(value: Int) : SetOnce<Int>(value) {
- fun set(v: String): Int {
- try {
- return this.set(v.toInt())
- } catch (e: NumberFormatException) {
- throw ArgumentsException("Invalid integer $v")
- }
- }
-}
+import com.android.hoststubgen.utils.ArgIterator
+import com.android.hoststubgen.utils.IntSetOnce
+import com.android.hoststubgen.utils.SetOnce
/**
* Options that can be set from command line arguments.
*/
class HostStubGenOptions(
- /** Input jar file*/
- var inJar: SetOnce<String> = SetOnce(""),
-
- /** Output jar file */
- var outJar: SetOnce<String?> = SetOnce(null),
-
- var inputJarDumpFile: SetOnce<String?> = SetOnce(null),
-
- var inputJarAsKeepAllFile: SetOnce<String?> = SetOnce(null),
-
- var keepAnnotations: MutableSet<String> = mutableSetOf(),
- var throwAnnotations: MutableSet<String> = mutableSetOf(),
- var removeAnnotations: MutableSet<String> = mutableSetOf(),
- var ignoreAnnotations: MutableSet<String> = mutableSetOf(),
- var keepClassAnnotations: MutableSet<String> = mutableSetOf(),
- var partiallyAllowedAnnotations: MutableSet<String> = mutableSetOf(),
- var redirectAnnotations: MutableSet<String> = mutableSetOf(),
-
- var substituteAnnotations: MutableSet<String> = mutableSetOf(),
- var redirectionClassAnnotations: MutableSet<String> = mutableSetOf(),
- var classLoadHookAnnotations: MutableSet<String> = mutableSetOf(),
- var keepStaticInitializerAnnotations: MutableSet<String> = mutableSetOf(),
+ /** Input jar file*/
+ var inJar: SetOnce<String> = SetOnce(""),
- var packageRedirects: MutableList<Pair<String, String>> = mutableListOf(),
+ /** Output jar file */
+ var outJar: SetOnce<String?> = SetOnce(null),
- var annotationAllowedClassesFile: SetOnce<String?> = SetOnce(null),
+ var inputJarDumpFile: SetOnce<String?> = SetOnce(null),
- var defaultClassLoadHook: SetOnce<String?> = SetOnce(null),
- var defaultMethodCallHook: SetOnce<String?> = SetOnce(null),
+ var inputJarAsKeepAllFile: SetOnce<String?> = SetOnce(null),
- var policyOverrideFiles: MutableList<String> = mutableListOf(),
+ var cleanUpOnError: SetOnce<Boolean> = SetOnce(false),
- var defaultPolicy: SetOnce<FilterPolicy> = SetOnce(FilterPolicy.Remove),
+ var statsFile: SetOnce<String?> = SetOnce(null),
- var cleanUpOnError: SetOnce<Boolean> = SetOnce(false),
+ var apiListFile: SetOnce<String?> = SetOnce(null),
- var deleteFinals: SetOnce<Boolean> = SetOnce(false),
+ var numShards: IntSetOnce = IntSetOnce(1),
+ var shard: IntSetOnce = IntSetOnce(0),
+) : HostStubGenClassProcessorOptions() {
- var enableClassChecker: SetOnce<Boolean> = SetOnce(false),
- var enablePreTrace: SetOnce<Boolean> = SetOnce(false),
- var enablePostTrace: SetOnce<Boolean> = SetOnce(false),
-
- var statsFile: SetOnce<String?> = SetOnce(null),
-
- var apiListFile: SetOnce<String?> = SetOnce(null),
-
- var numShards: IntSetOnce = IntSetOnce(1),
- var shard: IntSetOnce = IntSetOnce(0),
-) {
- companion object {
-
- private fun parsePackageRedirect(fromColonTo: String): Pair<String, String> {
- val colon = fromColonTo.indexOf(':')
- if ((colon < 1) || (colon + 1 >= fromColonTo.length)) {
- throw ArgumentsException("--package-redirect must be a colon-separated string")
- }
- // TODO check for duplicates
- return Pair(fromColonTo.substring(0, colon), fromColonTo.substring(colon + 1))
+ override fun checkArgs() {
+ if (!inJar.isSet) {
+ throw ArgumentsException("Required option missing: --in-jar")
+ }
+ if (!outJar.isSet) {
+ log.w("--out-jar is not set. $executableName will not generate jar files.")
+ }
+ if (numShards.isSet != shard.isSet) {
+ throw ArgumentsException("--num-shards and --shard-index must be used together")
}
- fun parseArgs(args: Array<String>): HostStubGenOptions {
- val ret = HostStubGenOptions()
-
- val ai = ArgIterator.withAtFiles(args)
-
- var allAnnotations = mutableSetOf<String>()
-
- fun ensureUniqueAnnotation(name: String): String {
- if (!allAnnotations.add(name)) {
- throw DuplicateAnnotationException(ai.current)
- }
- return name
+ if (numShards.isSet) {
+ if (shard.get >= numShards.get) {
+ throw ArgumentsException("--shard-index must be smaller than --num-shards")
}
+ }
+ }
- while (true) {
- val arg = ai.nextArgOptional() ?: break
-
- // Define some shorthands...
- fun nextArg(): String = ai.nextArgRequired(arg)
- fun MutableSet<String>.addUniqueAnnotationArg(): String =
- nextArg().also { this += ensureUniqueAnnotation(it) }
-
- if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
- continue
- }
- try {
- when (arg) {
- // TODO: Write help
- "-h", "--help" -> TODO("Help is not implemented yet")
-
- "--in-jar" -> ret.inJar.set(nextArg()).ensureFileExists()
- // We support both arguments because some AOSP dependencies
- // still use the old argument
- "--out-jar", "--out-impl-jar" -> ret.outJar.set(nextArg())
-
- "--policy-override-file" ->
- ret.policyOverrideFiles.add(nextArg().ensureFileExists())
-
- "--clean-up-on-error" -> ret.cleanUpOnError.set(true)
- "--no-clean-up-on-error" -> ret.cleanUpOnError.set(false)
-
- "--default-remove" -> ret.defaultPolicy.set(FilterPolicy.Remove)
- "--default-throw" -> ret.defaultPolicy.set(FilterPolicy.Throw)
- "--default-keep" -> ret.defaultPolicy.set(FilterPolicy.Keep)
-
- "--keep-annotation" ->
- ret.keepAnnotations.addUniqueAnnotationArg()
-
- "--keep-class-annotation" ->
- ret.keepClassAnnotations.addUniqueAnnotationArg()
-
- "--partially-allowed-annotation" ->
- ret.partiallyAllowedAnnotations.addUniqueAnnotationArg()
-
- "--throw-annotation" ->
- ret.throwAnnotations.addUniqueAnnotationArg()
-
- "--remove-annotation" ->
- ret.removeAnnotations.addUniqueAnnotationArg()
-
- "--ignore-annotation" ->
- ret.ignoreAnnotations.addUniqueAnnotationArg()
-
- "--substitute-annotation" ->
- ret.substituteAnnotations.addUniqueAnnotationArg()
-
- "--redirect-annotation" ->
- ret.redirectAnnotations.addUniqueAnnotationArg()
-
- "--redirection-class-annotation" ->
- ret.redirectionClassAnnotations.addUniqueAnnotationArg()
-
- "--class-load-hook-annotation" ->
- ret.classLoadHookAnnotations.addUniqueAnnotationArg()
-
- "--keep-static-initializer-annotation" ->
- ret.keepStaticInitializerAnnotations.addUniqueAnnotationArg()
-
- "--package-redirect" ->
- ret.packageRedirects += parsePackageRedirect(nextArg())
-
- "--annotation-allowed-classes-file" ->
- ret.annotationAllowedClassesFile.set(nextArg())
-
- "--default-class-load-hook" ->
- ret.defaultClassLoadHook.set(nextArg())
-
- "--default-method-call-hook" ->
- ret.defaultMethodCallHook.set(nextArg())
-
- "--gen-keep-all-file" ->
- ret.inputJarAsKeepAllFile.set(nextArg())
-
- "--delete-finals" -> ret.deleteFinals.set(true)
-
- // Following options are for debugging.
- "--enable-class-checker" -> ret.enableClassChecker.set(true)
- "--no-class-checker" -> ret.enableClassChecker.set(false)
+ override fun parseOption(option: String, ai: ArgIterator): Boolean {
+ // Define some shorthands...
+ fun nextArg(): String = ai.nextArgRequired(option)
- "--enable-pre-trace" -> ret.enablePreTrace.set(true)
- "--no-pre-trace" -> ret.enablePreTrace.set(false)
+ when (option) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
- "--enable-post-trace" -> ret.enablePostTrace.set(true)
- "--no-post-trace" -> ret.enablePostTrace.set(false)
+ "--in-jar" -> inJar.set(nextArg()).ensureFileExists()
+ // We support both arguments because some AOSP dependencies
+ // still use the old argument
+ "--out-jar", "--out-impl-jar" -> outJar.set(nextArg())
- "--gen-input-dump-file" -> ret.inputJarDumpFile.set(nextArg())
+ "--clean-up-on-error" -> cleanUpOnError.set(true)
+ "--no-clean-up-on-error" -> cleanUpOnError.set(false)
- "--stats-file" -> ret.statsFile.set(nextArg())
- "--supported-api-list-file" -> ret.apiListFile.set(nextArg())
+ "--gen-input-dump-file" -> inputJarDumpFile.set(nextArg())
+ "--gen-keep-all-file" -> inputJarAsKeepAllFile.set(nextArg())
- "--num-shards" -> ret.numShards.set(nextArg()).also {
- if (it < 1) {
- throw ArgumentsException("$arg must be positive integer")
- }
- }
- "--shard-index" -> ret.shard.set(nextArg()).also {
- if (it < 0) {
- throw ArgumentsException("$arg must be positive integer or zero")
- }
- }
+ "--stats-file" -> statsFile.set(nextArg())
+ "--supported-api-list-file" -> apiListFile.set(nextArg())
- else -> throw ArgumentsException("Unknown option: $arg")
- }
- } catch (e: SetOnce.SetMoreThanOnceException) {
- throw ArgumentsException("Duplicate or conflicting argument found: $arg")
+ "--num-shards" -> numShards.set(nextArg()).also {
+ if (it < 1) {
+ throw ArgumentsException("$option must be positive integer")
}
}
-
- if (!ret.inJar.isSet) {
- throw ArgumentsException("Required option missing: --in-jar")
- }
- if (!ret.outJar.isSet) {
- log.w("--out-jar is not set. $executableName will not generate jar files.")
- }
- if (ret.numShards.isSet != ret.shard.isSet) {
- throw ArgumentsException("--num-shards and --shard-index must be used together")
- }
-
- if (ret.numShards.isSet) {
- if (ret.shard.get >= ret.numShards.get) {
- throw ArgumentsException("--shard-index must be smaller than --num-shards")
+ "--shard-index" -> shard.set(nextArg()).also {
+ if (it < 0) {
+ throw ArgumentsException("$option must be positive integer or zero")
}
}
- return ret
- }
- }
-
- override fun toString(): String {
- return """
- HostStubGenOptions{
- inJar='$inJar',
- outJar='$outJar',
- inputJarDumpFile=$inputJarDumpFile,
- inputJarAsKeepAllFile=$inputJarAsKeepAllFile,
- keepAnnotations=$keepAnnotations,
- throwAnnotations=$throwAnnotations,
- removeAnnotations=$removeAnnotations,
- ignoreAnnotations=$ignoreAnnotations,
- keepClassAnnotations=$keepClassAnnotations,
- partiallyAllowedAnnotations=$partiallyAllowedAnnotations,
- substituteAnnotations=$substituteAnnotations,
- nativeSubstituteAnnotations=$redirectionClassAnnotations,
- classLoadHookAnnotations=$classLoadHookAnnotations,
- keepStaticInitializerAnnotations=$keepStaticInitializerAnnotations,
- packageRedirects=$packageRedirects,
- annotationAllowedClassesFile=$annotationAllowedClassesFile,
- defaultClassLoadHook=$defaultClassLoadHook,
- defaultMethodCallHook=$defaultMethodCallHook,
- policyOverrideFiles=${policyOverrideFiles.toTypedArray().contentToString()},
- defaultPolicy=$defaultPolicy,
- deleteFinals=$deleteFinals,
- cleanUpOnError=$cleanUpOnError,
- enableClassChecker=$enableClassChecker,
- enablePreTrace=$enablePreTrace,
- enablePostTrace=$enablePostTrace,
- statsFile=$statsFile,
- apiListFile=$apiListFile,
- numShards=$numShards,
- shard=$shard,
- }
- """.trimIndent()
- }
-}
-
-class ArgIterator(
- private val args: List<String>,
- private var currentIndex: Int = -1
-) {
- val current: String
- get() = args.get(currentIndex)
-
- /**
- * Get the next argument, or [null] if there's no more arguments.
- */
- fun nextArgOptional(): String? {
- if ((currentIndex + 1) >= args.size) {
- return null
+ else -> return super.parseOption(option, ai)
}
- return args.get(++currentIndex)
- }
- /**
- * Get the next argument, or throw if
- */
- fun nextArgRequired(argName: String): String {
- nextArgOptional().let {
- if (it == null) {
- throw ArgumentsException("Missing parameter for option $argName")
- }
- if (it.isEmpty()) {
- throw ArgumentsException("Parameter can't be empty for option $argName")
- }
- return it
- }
+ return true
}
- companion object {
- fun withAtFiles(args: Array<String>): ArgIterator {
- return ArgIterator(expandAtFiles(args))
- }
- }
-}
-
-/**
- * Scan the arguments, and if any of them starts with an `@`, then load from the file
- * and use its content as arguments.
- *
- * In order to pass an argument that starts with an '@', use '@@' instead.
- *
- * In this file, each line is treated as a single argument.
- *
- * The file can contain '#' as comments.
- */
-private fun expandAtFiles(args: Array<String>): List<String> {
- val ret = mutableListOf<String>()
-
- args.forEach { arg ->
- if (arg.startsWith("@@")) {
- ret += arg.substring(1)
- return@forEach
- } else if (!arg.startsWith('@')) {
- ret += arg
- return@forEach
- }
- // Read from the file, and add each line to the result.
- val filename = arg.substring(1).ensureFileExists()
-
- log.v("Expanding options file $filename")
-
- BufferedReader(FileReader(filename)).use { reader ->
- while (true) {
- var line = reader.readLine()
- if (line == null) {
- break // EOF
- }
-
- line = normalizeTextLine(line)
- if (line.isNotEmpty()) {
- ret += line
- }
- }
- }
+ override fun dumpFields(): String {
+ return """
+ inJar=$inJar,
+ outJar=$outJar,
+ inputJarDumpFile=$inputJarDumpFile,
+ inputJarAsKeepAllFile=$inputJarAsKeepAllFile,
+ cleanUpOnError=$cleanUpOnError,
+ statsFile=$statsFile,
+ apiListFile=$apiListFile,
+ numShards=$numShards,
+ shard=$shard,
+ """.trimIndent() + '\n' + super.dumpFields()
}
- return ret
}
diff --git a/ravenwood/tools/ravenhelper/Android.bp b/ravenwood/tools/ravenhelper/Android.bp
index 3da6dd824c37..b27914750618 100644
--- a/ravenwood/tools/ravenhelper/Android.bp
+++ b/ravenwood/tools/ravenhelper/Android.bp
@@ -14,13 +14,7 @@ java_binary_host {
static_libs: [
"guava",
"hoststubgen-lib",
- "junit",
"metalava-gradle-plugin-deps", // Get lint/PSI related classes from here.
- "ow2-asm",
- "ow2-asm-analysis",
- "ow2-asm-commons",
- "ow2-asm-tree",
- "ow2-asm-util",
],
visibility: ["//visibility:public"],
}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt
index 08bd95fd532b..f7fd0804c151 100644
--- a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt
@@ -15,11 +15,11 @@
*/
package com.android.platform.test.ravenwood.ravenhelper.policytoannot
-import com.android.hoststubgen.ArgIterator
import com.android.hoststubgen.ArgumentsException
-import com.android.hoststubgen.SetOnce
import com.android.hoststubgen.ensureFileExists
-import com.android.hoststubgen.log
+import com.android.hoststubgen.utils.ArgIterator
+import com.android.hoststubgen.utils.BaseOptions
+import com.android.hoststubgen.utils.SetOnce
/**
* Options for the "ravenhelper pta" subcommand.
@@ -39,68 +39,48 @@ class PtaOptions(
/** Dump the operations (for debugging) */
var dumpOperations: SetOnce<Boolean> = SetOnce(false),
-) {
- companion object {
- fun parseArgs(args: List<String>): PtaOptions {
- val ret = PtaOptions()
- val ai = ArgIterator.withAtFiles(args.toTypedArray())
+) : BaseOptions() {
- while (true) {
- val arg = ai.nextArgOptional() ?: break
+ override fun parseOption(option: String, ai: ArgIterator): Boolean {
+ fun nextArg(): String = ai.nextArgRequired(option)
- fun nextArg(): String = ai.nextArgRequired(arg)
+ when (option) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
- if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
- continue
- }
- try {
- when (arg) {
- // TODO: Write help
- "-h", "--help" -> TODO("Help is not implemented yet")
+ "-p", "--policy-override-file" ->
+ policyOverrideFiles.add(nextArg().ensureFileExists())
- "-p", "--policy-override-file" ->
- ret.policyOverrideFiles.add(nextArg().ensureFileExists())
+ "-a", "--annotation-allowed-classes-file" ->
+ annotationAllowedClassesFile.set(nextArg().ensureFileExists())
- "-a", "--annotation-allowed-classes-file" ->
- ret.annotationAllowedClassesFile.set(nextArg().ensureFileExists())
+ "-s", "--src" -> sourceFilesOrDirectories.add(nextArg().ensureFileExists())
+ "--dump" -> dumpOperations.set(true)
+ "-o", "--output-script" -> outputScriptFile.set(nextArg())
- "-s", "--src" ->
- ret.sourceFilesOrDirectories.add(nextArg().ensureFileExists())
-
- "--dump" ->
- ret.dumpOperations.set(true)
-
- "-o", "--output-script" ->
- ret.outputScriptFile.set(nextArg())
-
- else -> throw ArgumentsException("Unknown option: $arg")
- }
- } catch (e: SetOnce.SetMoreThanOnceException) {
- throw ArgumentsException("Duplicate or conflicting argument found: $arg")
- }
- }
+ else -> return false
+ }
- if (ret.policyOverrideFiles.size == 0) {
- throw ArgumentsException("Must specify at least one policy file")
- }
+ return true
+ }
- if (ret.sourceFilesOrDirectories.size == 0) {
- throw ArgumentsException("Must specify at least one source path")
- }
+ override fun checkArgs() {
+ if (policyOverrideFiles.size == 0) {
+ throw ArgumentsException("Must specify at least one policy file")
+ }
- return ret
+ if (sourceFilesOrDirectories.size == 0) {
+ throw ArgumentsException("Must specify at least one source path")
}
}
- override fun toString(): String {
+ override fun dumpFields(): String {
return """
- PtaOptions{
- policyOverrideFiles=$policyOverrideFiles
- annotationAllowedClassesFile=$annotationAllowedClassesFile
- sourceFilesOrDirectories=$sourceFilesOrDirectories
- outputScriptFile=$outputScriptFile
- dumpOperations=$dumpOperations
- }
- """.trimIndent()
+ policyOverrideFiles=$policyOverrideFiles
+ annotationAllowedClassesFile=$annotationAllowedClassesFile
+ sourceFilesOrDirectories=$sourceFilesOrDirectories
+ outputScriptFile=$outputScriptFile
+ dumpOperations=$dumpOperations
+ """.trimIndent()
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
index a7f481a02533..fd6f732a06ce 100644
--- a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
@@ -39,7 +39,7 @@ import java.util.regex.Pattern
*/
class PtaProcessor : SubcommandHandler {
override fun handle(args: List<String>) {
- val options = PtaOptions.parseArgs(args)
+ val options = PtaOptions().apply { parseArgs(args) }
log.v("Options: $options")
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt
index ee200bb39df2..8b95843f08a6 100644
--- a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt
@@ -15,11 +15,11 @@
*/
package com.android.platform.test.ravenwood.ravenhelper.sourcemap
-import com.android.hoststubgen.ArgIterator
import com.android.hoststubgen.ArgumentsException
-import com.android.hoststubgen.SetOnce
import com.android.hoststubgen.ensureFileExists
-import com.android.hoststubgen.log
+import com.android.hoststubgen.utils.ArgIterator
+import com.android.hoststubgen.utils.BaseOptions
+import com.android.hoststubgen.utils.SetOnce
/**
* Options for the "ravenhelper map" subcommand.
@@ -36,60 +36,36 @@ class MapOptions(
/** Text to insert. */
var text: SetOnce<String?> = SetOnce(null),
-) {
- companion object {
- fun parseArgs(args: List<String>): MapOptions {
- val ret = MapOptions()
- val ai = ArgIterator.withAtFiles(args.toTypedArray())
-
- while (true) {
- val arg = ai.nextArgOptional() ?: break
-
- fun nextArg(): String = ai.nextArgRequired(arg)
-
- if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
- continue
- }
- try {
- when (arg) {
- // TODO: Write help
- "-h", "--help" -> TODO("Help is not implemented yet")
-
- "-s", "--src" ->
- ret.sourceFilesOrDirectories.add(nextArg().ensureFileExists())
-
- "-i", "--input" ->
- ret.targetMethodFiles.add(nextArg().ensureFileExists())
-
- "-o", "--output-script" ->
- ret.outputScriptFile.set(nextArg())
-
- "-t", "--text" ->
- ret.text.set(nextArg())
-
- else -> throw ArgumentsException("Unknown option: $arg")
- }
- } catch (e: SetOnce.SetMoreThanOnceException) {
- throw ArgumentsException("Duplicate or conflicting argument found: $arg")
- }
- }
+) : BaseOptions() {
+
+ override fun parseOption(option: String, ai: ArgIterator): Boolean {
+ fun nextArg(): String = ai.nextArgRequired(option)
+
+ when (option) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
+ "-s", "--src" -> sourceFilesOrDirectories.add(nextArg().ensureFileExists())
+ "-i", "--input" -> targetMethodFiles.add(nextArg().ensureFileExists())
+ "-o", "--output-script" -> outputScriptFile.set(nextArg())
+ "-t", "--text" -> text.set(nextArg())
+ else -> return false
+ }
- if (ret.sourceFilesOrDirectories.size == 0) {
- throw ArgumentsException("Must specify at least one source path")
- }
+ return true
+ }
- return ret
+ override fun checkArgs() {
+ if (sourceFilesOrDirectories.size == 0) {
+ throw ArgumentsException("Must specify at least one source path")
}
}
- override fun toString(): String {
+ override fun dumpFields(): String {
return """
- PtaOptions{
- sourceFilesOrDirectories=$sourceFilesOrDirectories
- targetMethods=$targetMethodFiles
- outputScriptFile=$outputScriptFile
- text=$text
- }
- """.trimIndent()
+ sourceFilesOrDirectories=$sourceFilesOrDirectories
+ targetMethods=$targetMethodFiles
+ outputScriptFile=$outputScriptFile
+ text=$text
+ """.trimIndent()
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt
index 8085253895f9..f1c139891b2d 100644
--- a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt
@@ -35,7 +35,7 @@ import java.io.FileReader
*/
class MarkMethodHandler : SubcommandHandler {
override fun handle(args: List<String>) {
- val options = MapOptions.parseArgs(args)
+ val options = MapOptions().apply { parseArgs(args) }
log.i("Options: $options")
diff --git a/ravenwood/tools/ravenizer/Android.bp b/ravenwood/tools/ravenizer/Android.bp
index a52a04b44f2d..957e20647d44 100644
--- a/ravenwood/tools/ravenizer/Android.bp
+++ b/ravenwood/tools/ravenizer/Android.bp
@@ -13,12 +13,6 @@ java_binary_host {
srcs: ["src/**/*.kt"],
static_libs: [
"hoststubgen-lib",
- "ow2-asm",
- "ow2-asm-analysis",
- "ow2-asm-commons",
- "ow2-asm-tree",
- "ow2-asm-util",
- "junit",
"ravenwood-junit-for-ravenizer",
],
visibility: ["//visibility:public"],
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerMain.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerMain.kt
index aee453020fb4..7f4829ec6127 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerMain.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerMain.kt
@@ -21,6 +21,21 @@ import com.android.hoststubgen.LogLevel
import com.android.hoststubgen.executableName
import com.android.hoststubgen.log
import com.android.hoststubgen.runMainWithBoilerplate
+import java.nio.file.Paths
+import kotlin.io.path.exists
+
+/**
+ * If this file exits, we also read options from it. This is "unsafe" because it could break
+ * incremental builds, if it sets any flag that affects the output file.
+ * (however, for now, there's no such options.)
+ *
+ * For example, to enable verbose logging, do `echo '-v' > ~/.raveniezr-unsafe`
+ *
+ * (but even the content of this file changes, soong won't rerun the command, so you need to
+ * remove the output first and then do a build again.)
+ */
+private val RAVENIZER_DOTFILE = System.getenv("HOME") + "/.ravenizer-unsafe"
+
/**
* Entry point.
@@ -30,7 +45,15 @@ fun main(args: Array<String>) {
log.setConsoleLogLevel(LogLevel.Info)
runMainWithBoilerplate {
- val options = RavenizerOptions.parseArgs(args)
+ var newArgs = args.asList()
+ if (Paths.get(RAVENIZER_DOTFILE).exists()) {
+ log.i("Reading options from $RAVENIZER_DOTFILE")
+ newArgs = args.toMutableList().apply {
+ add(0, "@$RAVENIZER_DOTFILE")
+ }
+ }
+
+ val options = RavenizerOptions().apply { parseArgs(newArgs) }
log.i("$executableName started")
log.v("Options: $options")
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt
index a0e5599c0a7c..2c0365404ab6 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt
@@ -15,25 +15,11 @@
*/
package com.android.platform.test.ravenwood.ravenizer
-import com.android.hoststubgen.ArgIterator
import com.android.hoststubgen.ArgumentsException
-import com.android.hoststubgen.SetOnce
import com.android.hoststubgen.ensureFileExists
-import com.android.hoststubgen.log
-import java.nio.file.Paths
-import kotlin.io.path.exists
-
-/**
- * If this file exits, we also read options from it. This is "unsafe" because it could break
- * incremental builds, if it sets any flag that affects the output file.
- * (however, for now, there's no such options.)
- *
- * For example, to enable verbose logging, do `echo '-v' > ~/.raveniezr-unsafe`
- *
- * (but even the content of this file changes, soong won't rerun the command, so you need to
- * remove the output first and then do a build again.)
- */
-private val RAVENIZER_DOTFILE = System.getenv("HOME") + "/.raveniezr-unsafe"
+import com.android.hoststubgen.utils.ArgIterator
+import com.android.hoststubgen.utils.BaseOptions
+import com.android.hoststubgen.utils.SetOnce
class RavenizerOptions(
/** Input jar file*/
@@ -50,72 +36,49 @@ class RavenizerOptions(
/** Whether to remove mockito and dexmaker classes. */
var stripMockito: SetOnce<Boolean> = SetOnce(false),
-) {
- companion object {
-
- fun parseArgs(origArgs: Array<String>): RavenizerOptions {
- val args = origArgs.toMutableList()
- if (Paths.get(RAVENIZER_DOTFILE).exists()) {
- log.i("Reading options from $RAVENIZER_DOTFILE")
- args.add(0, "@$RAVENIZER_DOTFILE")
- }
-
- val ret = RavenizerOptions()
- val ai = ArgIterator.withAtFiles(args.toTypedArray())
-
- while (true) {
- val arg = ai.nextArgOptional()
- if (arg == null) {
- break
- }
-
- fun nextArg(): String = ai.nextArgRequired(arg)
-
- if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
- continue
- }
- try {
- when (arg) {
- // TODO: Write help
- "-h", "--help" -> TODO("Help is not implemented yet")
-
- "--in-jar" -> ret.inJar.set(nextArg()).ensureFileExists()
- "--out-jar" -> ret.outJar.set(nextArg())
-
- "--enable-validation" -> ret.enableValidation.set(true)
- "--disable-validation" -> ret.enableValidation.set(false)
-
- "--fatal-validation" -> ret.fatalValidation.set(true)
- "--no-fatal-validation" -> ret.fatalValidation.set(false)
-
- "--strip-mockito" -> ret.stripMockito.set(true)
- "--no-strip-mockito" -> ret.stripMockito.set(false)
-
- else -> throw ArgumentsException("Unknown option: $arg")
- }
- } catch (e: SetOnce.SetMoreThanOnceException) {
- throw ArgumentsException("Duplicate or conflicting argument found: $arg")
- }
- }
-
- if (!ret.inJar.isSet) {
- throw ArgumentsException("Required option missing: --in-jar")
- }
- if (!ret.outJar.isSet) {
- throw ArgumentsException("Required option missing: --out-jar")
- }
- return ret
+) : BaseOptions() {
+
+ override fun parseOption(option: String, ai: ArgIterator): Boolean {
+ fun nextArg(): String = ai.nextArgRequired(option)
+
+ when (option) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
+
+ "--in-jar" -> inJar.set(nextArg()).ensureFileExists()
+ "--out-jar" -> outJar.set(nextArg())
+
+ "--enable-validation" -> enableValidation.set(true)
+ "--disable-validation" -> enableValidation.set(false)
+
+ "--fatal-validation" -> fatalValidation.set(true)
+ "--no-fatal-validation" -> fatalValidation.set(false)
+
+ "--strip-mockito" -> stripMockito.set(true)
+ "--no-strip-mockito" -> stripMockito.set(false)
+
+ else -> return false
+ }
+
+ return true
+ }
+
+ override fun checkArgs() {
+ if (!inJar.isSet) {
+ throw ArgumentsException("Required option missing: --in-jar")
+ }
+ if (!outJar.isSet) {
+ throw ArgumentsException("Required option missing: --out-jar")
}
}
- override fun toString(): String {
+ override fun dumpFields(): String {
return """
- RavenizerOptions{
- inJar=$inJar,
- outJar=$outJar,
- enableValidation=$enableValidation,
- fatalValidation=$fatalValidation,
- }
- """.trimIndent()
+ inJar=$inJar,
+ outJar=$outJar,
+ enableValidation=$enableValidation,
+ fatalValidation=$fatalValidation,
+ stripMockito=$stripMockito,
+ """.trimIndent()
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 42834ce20783..c49151dd5e30 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -287,7 +287,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
public static final int INVALID_SERVICE_ID = -1;
- // Each service has an ID. Also provide one for magnification gesture handling
+ // Each service has an ID. Also provide one for magnification gesture handling.
+ // This ID is also used for mouse event handling.
public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0;
private static int sIdCounter = MAGNIFICATION_GESTURE_HANDLER_ID + 1;
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
index 57bbb4a7a0a7..90ddc43ae3ed 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
@@ -86,13 +86,6 @@ public class AutoclickTypePanel {
})
public @interface Corner {}
- private static final @Corner int[] CORNER_ROTATION_ORDER = {
- CORNER_BOTTOM_RIGHT,
- CORNER_BOTTOM_LEFT,
- CORNER_TOP_LEFT,
- CORNER_TOP_RIGHT
- };
-
// An interface exposed to {@link AutoclickController) to handle different actions on the panel,
// including changing autoclick type, pausing/resuming autoclick.
public interface ClickPanelControllerInterface {
@@ -136,10 +129,9 @@ public class AutoclickTypePanel {
// Whether autoclick is paused.
private boolean mPaused = false;
- // Tracks the current corner position of the panel using an index into CORNER_ROTATION_ORDER
- // array. This allows the panel to cycle through screen corners in a defined sequence when
- // repositioned.
- private int mCurrentCornerIndex = 0;
+
+ // The current corner position of the panel, default to bottom right.
+ private @Corner int mCurrentCorner = CORNER_BOTTOM_RIGHT;
private final LinearLayout mLeftClickButton;
private final LinearLayout mRightClickButton;
@@ -257,13 +249,13 @@ public class AutoclickTypePanel {
params.gravity = Gravity.START | Gravity.TOP;
// Set the current corner to be bottom-left to ensure that the subsequent reposition
// action rotates the panel clockwise from bottom-left towards top-left.
- mCurrentCornerIndex = 1;
+ mCurrentCorner = CORNER_BOTTOM_LEFT;
} else {
// Snap to right edge. Set params.gravity to make sure x, y offsets from correct anchor.
params.gravity = Gravity.END | Gravity.TOP;
// Set the current corner to be top-right to ensure that the subsequent reposition
// action rotates the panel clockwise from top-right towards bottom-right.
- mCurrentCornerIndex = 3;
+ mCurrentCorner = CORNER_TOP_RIGHT;
}
// Apply final position: set params.x to be edge margin, params.y to maintain vertical
@@ -415,10 +407,10 @@ public class AutoclickTypePanel {
/** Moves the panel to the next corner in clockwise direction. */
private void moveToNextCorner() {
- @Corner int nextCornerIndex = (mCurrentCornerIndex + 1) % CORNER_ROTATION_ORDER.length;
- mCurrentCornerIndex = nextCornerIndex;
+ @Corner int nextCorner = (mCurrentCorner + 1) % 4;
+ mCurrentCorner = nextCorner;
- setPanelPositionForCorner(mParams, mCurrentCornerIndex);
+ setPanelPositionForCorner(mParams, mCurrentCorner);
mWindowManager.updateViewLayout(mContentView, mParams);
}
@@ -457,7 +449,7 @@ public class AutoclickTypePanel {
String.valueOf(mParams.gravity),
String.valueOf(mParams.x),
String.valueOf(mParams.y),
- String.valueOf(mCurrentCornerIndex)
+ String.valueOf(mCurrentCorner)
});
Settings.Secure.putStringForUser(mContext.getContentResolver(),
ACCESSIBILITY_AUTOCLICK_PANEL_POSITION, positionString, mUserId);
@@ -473,7 +465,7 @@ public class AutoclickTypePanel {
ACCESSIBILITY_AUTOCLICK_PANEL_POSITION, mUserId);
if (savedPosition == null) {
setPanelPositionForCorner(mParams, CORNER_BOTTOM_RIGHT);
- mCurrentCornerIndex = 0;
+ mCurrentCorner = CORNER_BOTTOM_RIGHT;
return;
}
@@ -481,7 +473,7 @@ public class AutoclickTypePanel {
String[] parts = TextUtils.split(savedPosition, POSITION_DELIMITER);
if (!isValidPositionParts(parts)) {
setPanelPositionForCorner(mParams, CORNER_BOTTOM_RIGHT);
- mCurrentCornerIndex = 0;
+ mCurrentCorner = CORNER_BOTTOM_RIGHT;
return;
}
@@ -489,7 +481,7 @@ public class AutoclickTypePanel {
mParams.gravity = Integer.parseInt(parts[0]);
mParams.x = Integer.parseInt(parts[1]);
mParams.y = Integer.parseInt(parts[2]);
- mCurrentCornerIndex = Integer.parseInt(parts[3]);
+ mCurrentCorner = Integer.parseInt(parts[3]);
}
private boolean isValidPositionParts(String[] parts) {
@@ -538,8 +530,8 @@ public class AutoclickTypePanel {
@VisibleForTesting
@Corner
- int getCurrentCornerIndexForTesting() {
- return mCurrentCornerIndex;
+ int getCurrentCornerForTesting() {
+ return mCurrentCorner;
}
@VisibleForTesting
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index 11b8ccb70dfb..004b3ffcb02b 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -121,6 +121,8 @@ public class FullScreenMagnificationController implements
@NonNull private final Supplier<MagnificationThumbnail> mThumbnailSupplier;
@NonNull private final Supplier<Boolean> mMagnificationConnectionStateSupplier;
+ private boolean mIsPointerMotionFilterInstalled = false;
+
/**
* This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
* magnification information per display.
@@ -830,9 +832,17 @@ public class FullScreenMagnificationController implements
return;
}
- final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
- final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
- if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
+ setOffset(mCurrentMagnificationSpec.offsetX - offsetX,
+ mCurrentMagnificationSpec.offsetY - offsetY, id);
+ }
+
+ @GuardedBy("mLock")
+ void setOffset(float offsetX, float offsetY, int id) {
+ if (!mRegistered) {
+ return;
+ }
+
+ if (updateCurrentSpecWithOffsetsLocked(offsetX, offsetY)) {
onMagnificationChangedLocked(/* isScaleTransient= */ false);
}
if (id != INVALID_SERVICE_ID) {
@@ -1065,6 +1075,7 @@ public class FullScreenMagnificationController implements
if (display.register()) {
mDisplays.put(displayId, display);
mScreenStateObserver.registerIfNecessary();
+ configurePointerMotionFilter(true);
}
}
}
@@ -1613,6 +1624,28 @@ public class FullScreenMagnificationController implements
}
/**
+ * Sets the offset of the magnified region.
+ *
+ * @param displayId The logical display id.
+ * @param offsetX the offset of the magnified region in the X coordinate, in current
+ * screen pixels.
+ * @param offsetY the offset of the magnified region in the Y coordinate, in current
+ * screen pixels.
+ * @param id the ID of the service requesting the change
+ */
+ @SuppressWarnings("GuardedBy")
+ // errorprone cannot recognize an inner class guarded by an outer class member.
+ public void setOffset(int displayId, float offsetX, float offsetY, int id) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return;
+ }
+ display.setOffset(offsetX, offsetY, id);
+ }
+ }
+
+ /**
* Offsets the magnified region. Note that the offsetX and offsetY values actually move in the
* opposite direction as the offsets passed in here.
*
@@ -1885,6 +1918,7 @@ public class FullScreenMagnificationController implements
}
if (!hasRegister) {
mScreenStateObserver.unregister();
+ configurePointerMotionFilter(false);
}
}
@@ -1900,6 +1934,22 @@ public class FullScreenMagnificationController implements
}
}
+ private void configurePointerMotionFilter(boolean enabled) {
+ if (!Flags.enableMagnificationFollowsMouseWithPointerMotionFilter()) {
+ return;
+ }
+ if (enabled == mIsPointerMotionFilterInstalled) {
+ return;
+ }
+ if (!enabled) {
+ mControllerCtx.getInputManager().registerAccessibilityPointerMotionFilter(null);
+ } else {
+ mControllerCtx.getInputManager().registerAccessibilityPointerMotionFilter(
+ new FullScreenMagnificationPointerMotionEventFilter(this));
+ }
+ mIsPointerMotionFilterInstalled = enabled;
+ }
+
private boolean traceEnabled() {
return mControllerCtx.getTraceManager().isA11yTracingEnabledForTypes(
FLAGS_WINDOW_MANAGER_INTERNAL);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index e0dd8b601a3d..59b4a1613e08 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -182,6 +182,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private final int mMinimumVelocity;
private final int mMaximumVelocity;
+ @Nullable
private final MouseEventHandler mMouseEventHandler;
public FullScreenMagnificationGestureHandler(
@@ -313,7 +314,9 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mOverscrollEdgeSlop = context.getResources().getDimensionPixelSize(
R.dimen.accessibility_fullscreen_magnification_gesture_edge_slop);
mIsWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
- mMouseEventHandler = new MouseEventHandler(mFullScreenMagnificationController);
+ mMouseEventHandler =
+ Flags.enableMagnificationFollowsMouseWithPointerMotionFilter()
+ ? null : new MouseEventHandler(mFullScreenMagnificationController);
if (mDetectShortcutTrigger) {
mScreenStateReceiver = new ScreenStateReceiver(context, this);
@@ -337,9 +340,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@Override
void handleMouseOrStylusEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- if (!mFullScreenMagnificationController.isActivated(mDisplayId)) {
+ if (mMouseEventHandler == null
+ || !mFullScreenMagnificationController.isActivated(mDisplayId)) {
return;
}
+
// TODO(b/354696546): Allow mouse/stylus to activate whichever display they are
// over, rather than only interacting with the current display.
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilter.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilter.java
new file mode 100644
index 000000000000..f1ba83e80d54
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.accessibility.magnification;
+
+import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID;
+
+import android.annotation.NonNull;
+
+import com.android.server.input.InputManagerInternal;
+
+/**
+ * Handles pointer motion event for full screen magnification.
+ * Responsible for controlling magnification's cursor following feature.
+ */
+public class FullScreenMagnificationPointerMotionEventFilter implements
+ InputManagerInternal.AccessibilityPointerMotionFilter {
+
+ private final FullScreenMagnificationController mController;
+
+ public FullScreenMagnificationPointerMotionEventFilter(
+ FullScreenMagnificationController controller) {
+ mController = controller;
+ }
+
+ /**
+ * This call happens on the input hot path and it is extremely performance sensitive. It
+ * also must not call back into native code.
+ */
+ @Override
+ @NonNull
+ public float[] filterPointerMotionEvent(float dx, float dy, float currentX, float currentY,
+ int displayId) {
+ if (!mController.isActivated(displayId)) {
+ // unrelated display.
+ return new float[]{dx, dy};
+ }
+
+ // TODO(361817142): implement centered and edge following types.
+
+ // Continuous cursor following.
+ float scale = mController.getScale(displayId);
+ final float newCursorX = currentX + dx;
+ final float newCursorY = currentY + dy;
+ mController.setOffset(displayId,
+ newCursorX - newCursorX * scale, newCursorY - newCursorY * scale,
+ MAGNIFICATION_GESTURE_HANDLER_ID);
+
+ // In the continuous mode, the cursor speed in physical display is kept.
+ // Thus, we don't consume any motion delta.
+ return new float[]{dx, dy};
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
index 9a353fbc45bf..867cd51e1c2b 100644
--- a/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
+++ b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
@@ -44,6 +44,7 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.internal.LifecycleOperationStorage;
import java.util.Set;
@@ -298,20 +299,22 @@ public class BackupAgentConnectionManager {
// Offload operation cancellation off the main thread as the cancellation callbacks
// might call out to BackupTransport. Other operations started on the same package
// before the cancellation callback has executed will also be cancelled by the callback.
- Runnable cancellationRunnable = () -> {
- // handleCancel() causes the PerformFullTransportBackupTask to go on to
- // tearDownAgentAndKill: that will unbindBackupAgent in the Activity Manager, so
- // that the package being backed up doesn't get stuck in restricted mode until the
- // backup time-out elapses.
- for (int token : mOperationStorage.operationTokensForPackage(packageName)) {
- if (DEBUG) {
- Slog.d(TAG,
- mUserIdMsg + "agentDisconnected: will handleCancel(all) for token:"
- + Integer.toHexString(token));
- }
- mUserBackupManagerService.handleCancel(token, true /* cancelAll */);
- }
- };
+ Runnable cancellationRunnable =
+ () -> {
+ // On handleCancel(), the operation will call unbindAgent() which will make
+ // sure the app doesn't get stuck in restricted mode.
+ for (int token : mOperationStorage.operationTokensForPackage(packageName)) {
+ if (DEBUG) {
+ Slog.d(
+ TAG,
+ mUserIdMsg
+ + "agentDisconnected: cancelling for token:"
+ + Integer.toHexString(token));
+ }
+ mUserBackupManagerService.handleCancel(
+ token, CancellationReason.AGENT_DISCONNECTED);
+ }
+ };
getThreadForCancellation(cancellationRunnable).start();
mAgentConnectLock.notifyAll();
diff --git a/services/backup/java/com/android/server/backup/BackupRestoreTask.java b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
index acaab0c54191..7ec5f0d786ed 100644
--- a/services/backup/java/com/android/server/backup/BackupRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
@@ -16,9 +16,12 @@
package com.android.server.backup;
-/**
- * Interface and methods used by the asynchronous-with-timeout backup/restore operations.
- */
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Interface and methods used by the asynchronous-with-timeout backup/restore operations. */
public interface BackupRestoreTask {
// Execute one tick of whatever state machine the task implements
@@ -27,6 +30,24 @@ public interface BackupRestoreTask {
// An operation that wanted a callback has completed
void operationComplete(long result);
- // An operation that wanted a callback has timed out
- void handleCancel(boolean cancelAll);
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ CancellationReason.TIMEOUT,
+ CancellationReason.AGENT_DISCONNECTED,
+ CancellationReason.EXTERNAL,
+ CancellationReason.SCHEDULED_JOB_STOPPED,
+ })
+ @interface CancellationReason {
+ // The task timed out.
+ int TIMEOUT = 0;
+ // The agent went away before the task was able to finish (e.g. due to an app crash).
+ int AGENT_DISCONNECTED = 1;
+ // An external caller cancelled the operation (e.g. via BackupManager#cancelBackups).
+ int EXTERNAL = 2;
+ // The job scheduler has stopped an ongoing scheduled backup pass.
+ int SCHEDULED_JOB_STOPPED = 3;
+ }
+
+ /** The task is cancelled for the given {@link CancellationReason}. */
+ void handleCancel(@CancellationReason int cancellationReason);
}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2143aaaa4cd6..b3af444ff9bd 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -102,6 +102,7 @@ import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.OperationStorage.OpState;
import com.android.server.backup.OperationStorage.OpType;
import com.android.server.backup.fullbackup.FullBackupEntry;
@@ -168,6 +169,7 @@ import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntConsumer;
/** System service that performs backup/restore operations. */
public class UserBackupManagerService {
@@ -1816,11 +1818,9 @@ public class UserBackupManagerService {
for (Integer token : operationsToCancel) {
mOperationStorage.cancelOperation(
- token, /* cancelAll */
- true,
- operationType -> {
- /* no callback needed here */
- });
+ token,
+ operationType -> {}, // no callback needed here
+ CancellationReason.EXTERNAL);
}
// We don't want the backup jobs to kick in any time soon.
// Reschedules them to run in the distant future.
@@ -1897,19 +1897,17 @@ public class UserBackupManagerService {
}
/** Cancel the operation associated with {@code token}. */
- public void handleCancel(int token, boolean cancelAll) {
+ public void handleCancel(int token, @CancellationReason int cancellationReason) {
// Remove all pending timeout messages of types OpType.BACKUP_WAIT and
// OpType.RESTORE_WAIT. On the other hand, OP_TYPE_BACKUP cannot time out and
// doesn't require cancellation.
- mOperationStorage.cancelOperation(
- token,
- cancelAll,
- operationType -> {
- if (operationType == OpType.BACKUP_WAIT
- || operationType == OpType.RESTORE_WAIT) {
- mBackupHandler.removeMessages(getMessageIdForOperationType(operationType));
+ IntConsumer timeoutCallback =
+ opType -> {
+ if (opType == OpType.BACKUP_WAIT || opType == OpType.RESTORE_WAIT) {
+ mBackupHandler.removeMessages(getMessageIdForOperationType(opType));
}
- });
+ };
+ mOperationStorage.cancelOperation(token, timeoutCallback, cancellationReason);
}
/** Returns {@code true} if a backup is currently running, else returns {@code false}. */
@@ -2219,20 +2217,17 @@ public class UserBackupManagerService {
// offload the mRunningFullBackupTask.handleCancel() call to another thread,
// as we might have to wait for mCancelLock
Runnable endFullBackupRunnable =
- new Runnable() {
- @Override
- public void run() {
- PerformFullTransportBackupTask pftbt = null;
- synchronized (mQueueLock) {
- if (mRunningFullBackupTask != null) {
- pftbt = mRunningFullBackupTask;
- }
- }
- if (pftbt != null) {
- Slog.i(TAG, mLogIdMsg + "Telling running backup to stop");
- pftbt.handleCancel(true);
+ () -> {
+ PerformFullTransportBackupTask pftbt = null;
+ synchronized (mQueueLock) {
+ if (mRunningFullBackupTask != null) {
+ pftbt = mRunningFullBackupTask;
}
}
+ if (pftbt != null) {
+ Slog.i(TAG, mLogIdMsg + "Telling running backup to stop");
+ pftbt.handleCancel(CancellationReason.SCHEDULED_JOB_STOPPED);
+ }
};
new Thread(endFullBackupRunnable, "end-full-backup").start();
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index 0d4364e14e03..7fc9ed3e0213 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -484,7 +484,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
}
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
final PackageInfo target = mCurrentTarget;
Slog.w(TAG, "adb backup cancel of " + target);
if (target != null) {
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 c182c2618fdf..f677c9dbf4d0 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -162,7 +162,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
// This is true when a backup operation for some package is in progress.
private volatile boolean mIsDoingBackup;
- private volatile boolean mCancelAll;
+ private volatile boolean mCancelled;
private final int mCurrentOpToken;
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private final BackupEligibilityRules mBackupEligibilityRules;
@@ -199,7 +199,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
if (backupManagerService.isBackupOperationInProgress()) {
Slog.d(TAG, "Skipping full backup. A backup is already in progress.");
- mCancelAll = true;
+ mCancelled = true;
return;
}
@@ -287,25 +287,23 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
}
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
synchronized (mCancelLock) {
- // We only support 'cancelAll = true' case for this task. Cancelling of a single package
-
- // due to timeout is handled by SinglePackageBackupRunner and
+ // This callback is only used for cancelling the entire backup operation. Cancelling of
+ // a single package due to timeout is handled by SinglePackageBackupRunner and
// SinglePackageBackupPreflight.
-
- if (!cancelAll) {
- Slog.wtf(TAG, "Expected cancelAll to be true.");
+ if (cancellationReason == CancellationReason.TIMEOUT) {
+ Slog.wtf(TAG, "This task cannot time out");
}
- if (mCancelAll) {
+ if (mCancelled) {
Slog.d(TAG, "Ignoring duplicate cancel call.");
return;
}
- mCancelAll = true;
+ mCancelled = true;
if (mIsDoingBackup) {
- mUserBackupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+ mUserBackupManagerService.handleCancel(mBackupRunnerOpToken, cancellationReason);
try {
// If we're running a backup we should be connected to a transport
BackupTransportClient transport =
@@ -410,7 +408,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
int backupPackageStatus;
long quota = Long.MAX_VALUE;
synchronized (mCancelLock) {
- if (mCancelAll) {
+ if (mCancelled) {
break;
}
backupPackageStatus = transport.performFullBackup(currentPackage,
@@ -478,7 +476,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
if (nRead > 0) {
out.write(buffer, 0, nRead);
synchronized (mCancelLock) {
- if (!mCancelAll) {
+ if (!mCancelled) {
backupPackageStatus = transport.sendBackupData(nRead);
}
}
@@ -509,7 +507,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
synchronized (mCancelLock) {
mIsDoingBackup = false;
// If mCancelCurrent is true, we have already called cancelFullBackup().
- if (!mCancelAll) {
+ if (!mCancelled) {
if (backupRunnerResult == BackupTransport.TRANSPORT_OK) {
// If we were otherwise in a good state, now interpret the final
// result based on what finishBackup() returns. If we're in a
@@ -607,7 +605,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
.sendBackupOnPackageResult(mBackupObserver, packageName,
BackupManager.ERROR_BACKUP_CANCELLED);
Slog.w(TAG, "Backup cancelled. package=" + packageName +
- ", cancelAll=" + mCancelAll);
+ ", entire session cancelled=" + mCancelled);
EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
mUserBackupManagerService.getBackupAgentConnectionManager().unbindAgent(
currentPackage.applicationInfo, /* allowKill= */ true);
@@ -654,7 +652,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
} finally {
- if (mCancelAll) {
+ if (mCancelled) {
backupRunStatus = BackupManager.ERROR_BACKUP_CANCELLED;
}
@@ -820,7 +818,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
}
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
if (DEBUG) {
Slog.i(TAG, "Preflight cancelled; failing");
}
@@ -974,7 +972,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
public void operationComplete(long result) { /* intentionally empty */ }
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
Slog.w(TAG, "Full backup cancel of " + mTarget.packageName);
mBackupManagerMonitorEventSender.monitorEvent(
@@ -984,7 +982,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
/* extras= */ null);
mIsCancelled = true;
// Cancel tasks spun off by this task.
- mUserBackupManagerService.handleCancel(mEphemeralToken, cancelAll);
+ mUserBackupManagerService.handleCancel(mEphemeralToken, cancellationReason);
mUserBackupManagerService.getBackupAgentConnectionManager().unbindAgent(
mTarget.applicationInfo, /* allowKill= */ true);
// Free up everyone waiting on this task and its children.
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 87cf8a313651..464dc2dfe1ec 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -34,6 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.OperationStorage;
import com.android.server.backup.TransportManager;
@@ -410,8 +411,8 @@ public class BackupHandler extends Handler {
case MSG_BACKUP_OPERATION_TIMEOUT:
case MSG_RESTORE_OPERATION_TIMEOUT: {
- Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1));
- backupManagerService.handleCancel(msg.arg1, false);
+ Slog.d(TAG, "Timeout for token=" + Integer.toHexString(msg.arg1));
+ backupManagerService.handleCancel(msg.arg1, CancellationReason.TIMEOUT);
break;
}
diff --git a/services/backup/java/com/android/server/backup/internal/LifecycleOperationStorage.java b/services/backup/java/com/android/server/backup/internal/LifecycleOperationStorage.java
index 0b974e2d0a8a..5aacb2f4f007 100644
--- a/services/backup/java/com/android/server/backup/internal/LifecycleOperationStorage.java
+++ b/services/backup/java/com/android/server/backup/internal/LifecycleOperationStorage.java
@@ -24,6 +24,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.OperationStorage;
import com.google.android.collect.Sets;
@@ -296,20 +297,18 @@ public class LifecycleOperationStorage implements OperationStorage {
}
/**
- * Cancel the operation associated with {@code token}. Cancellation may be
- * propagated to the operation's callback (a {@link BackupRestoreTask}) if
- * the operation has one, and the cancellation is due to the operation
- * timing out.
+ * Cancel the operation associated with {@code token}. Cancellation may be propagated to the
+ * operation's callback (a {@link BackupRestoreTask}) if the operation has one, and the
+ * cancellation is due to the operation timing out.
*
* @param token the operation token specified when registering the operation
- * @param cancelAll this is passed on when propagating the cancellation
- * @param operationTimedOutCallback a lambda that is invoked with the
- * operation type where the operation is
- * cancelled due to timeout, allowing the
- * caller to do type-specific clean-ups.
+ * @param operationTimedOutCallback a lambda that is invoked with the operation type where the
+ * operation is cancelled due to timeout, allowing the caller to do type-specific clean-ups.
*/
public void cancelOperation(
- int token, boolean cancelAll, IntConsumer operationTimedOutCallback) {
+ int token,
+ IntConsumer operationTimedOutCallback,
+ @CancellationReason int cancellationReason) {
// Notify any synchronous waiters
Operation op = null;
synchronized (mOperationsLock) {
@@ -343,7 +342,7 @@ public class LifecycleOperationStorage implements OperationStorage {
if (DEBUG) {
Slog.v(TAG, "[UserID:" + mUserId + " Invoking cancel on " + op.callback);
}
- op.callback.handleCancel(cancelAll);
+ op.callback.handleCancel(cancellationReason);
}
}
}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 494b9d59a238..8e7a23ccbb25 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -171,7 +171,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* complete backup should be performed.
*
* <p>This task is designed to run on a dedicated thread, with the exception of the {@link
- * #handleCancel(boolean)} method, which can be called from any thread.
+ * BackupRestoreTask#handleCancel(int)} method, which can be called from any thread.
*/
// TODO: Stop poking into BMS state and doing things for it (e.g. synchronizing on public locks)
// TODO: Consider having the caller responsible for some clean-up (like resetting state)
@@ -1208,13 +1208,13 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
*
* <p>Note: This method is inherently racy since there are no guarantees about how much of the
* task will be executed after you made the call.
- *
- * @param cancelAll MUST be {@code true}. Will be removed.
*/
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
// This is called in a thread different from the one that executes method run().
- Preconditions.checkArgument(cancelAll, "Can't partially cancel a key-value backup task");
+ Preconditions.checkArgument(
+ cancellationReason != CancellationReason.TIMEOUT,
+ "Key-value backup task cannot time out");
markCancel();
waitCancel();
}
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
index cb491c6f384e..f1829b6966a8 100644
--- a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -79,7 +79,7 @@ public class AdbRestoreFinishedLatch implements BackupRestoreTask {
}
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
Slog.w(TAG, "adb onRestoreFinished() timed out");
mLatch.countDown();
mOperationStorage.removeOperation(mCurrentOpToken);
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 707ae03b3964..1263146fe405 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -1307,7 +1307,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
// The app has timed out handling a restoring file
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
mOperationStorage.removeOperation(mEphemeralOpToken);
Slog.w(TAG, "Full-data restore target timed out; shutting down");
Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
@@ -1555,7 +1555,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
// A call to agent.doRestore() or agent.doRestoreFinished() has timed out
@Override
- public void handleCancel(boolean cancelAll) {
+ public void handleCancel(@CancellationReason int cancellationReason) {
mOperationStorage.removeOperation(mEphemeralOpToken);
Slog.e(TAG, "Timeout restoring application " + mCurrentPackage.packageName);
Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
diff --git a/services/companion/java/com/android/server/companion/association/AssociationDiskStore.java b/services/companion/java/com/android/server/companion/association/AssociationDiskStore.java
index ce7dcd0fa1d4..03107563ec22 100644
--- a/services/companion/java/com/android/server/companion/association/AssociationDiskStore.java
+++ b/services/companion/java/com/android/server/companion/association/AssociationDiskStore.java
@@ -299,14 +299,24 @@ public final class AssociationDiskStore {
public void writeLastRemovedAssociation(AssociationInfo association, String reason) {
Slog.i(TAG, "Writing last removed association=" + association.getId() + " to disk...");
+ // Remove indirect identifier i.e. Mac Address
+ AssociationInfo.Builder builder = new AssociationInfo.Builder(association)
+ .setDeviceMacAddress(null);
+ // Set a placeholder display name if it's null because Mac Address and display name can't be
+ // both null.
+ if (association.getDisplayName() == null) {
+ builder.setDisplayName("");
+ }
+ AssociationInfo redactedAssociation = builder.build();
+
final AtomicFile file = createStorageFileForUser(
- association.getUserId(), FILE_NAME_LAST_REMOVED_ASSOCIATION);
+ redactedAssociation.getUserId(), FILE_NAME_LAST_REMOVED_ASSOCIATION);
writeToFileSafely(file, out -> {
out.write(String.valueOf(System.currentTimeMillis()).getBytes());
out.write(' ');
out.write(reason.getBytes());
out.write(' ');
- out.write(association.toString().getBytes());
+ out.write(redactedAssociation.toString().getBytes());
});
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 2aaf6a9c2391..14d9d3f0c0a1 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -121,6 +121,13 @@ genrule {
out: ["com/android/server/location/contexthub/ContextHubStatsLog.java"],
}
+genrule {
+ name: "statslog-mediarouter-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module mediarouter --javaPackage com.android.server.media --javaClass MediaRouterStatsLog",
+ out: ["com/android/server/media/MediaRouterStatsLog.java"],
+}
+
java_library_static {
name: "services.core.unboosted",
defaults: [
@@ -136,6 +143,7 @@ java_library_static {
":android.hardware.tv.mediaquality-V1-java-source",
":statslog-art-java-gen",
":statslog-contexthub-java-gen",
+ ":statslog-mediarouter-java-gen",
":services.core-aidl-sources",
":services.core-sources",
":services.core.protologsrc",
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 296f7cfe93ba..f54027ec0272 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -514,6 +514,7 @@ final class UiModeManagerService extends SystemService {
mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
registerVrStateListener();
// register listeners
+ // LINT.IfChange(fi_cb)
context.getContentResolver()
.registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
false, mDarkThemeObserver, 0);
@@ -523,6 +524,7 @@ final class UiModeManagerService extends SystemService {
Secure.getUriFor(ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED),
false, mForceInvertStateObserver, UserHandle.USER_ALL);
}
+ // LINT.ThenChange(/core/java/android/view/ViewRootImpl.java:fi_cb)
context.getContentResolver().registerContentObserver(
Secure.getUriFor(Secure.CONTRAST_LEVEL), false,
mContrastObserver, UserHandle.USER_ALL);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 600b124ffbf6..79fdcca9f75d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -190,6 +190,7 @@ public class AccountManagerService
}
final Context mContext;
+ final PackageMonitor mPackageMonitor;
private static final int[] INTERESTING_APP_OPS = new int[] {
AppOpsManager.OP_GET_ACCOUNTS,
@@ -373,7 +374,7 @@ public class AccountManagerService
}, UserHandle.ALL, userFilter, null, null);
// Need to cancel account request notifications if the update/install can access the account
- new PackageMonitor() {
+ mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
// Called on a handler, and running as the system
@@ -397,7 +398,8 @@ public class AccountManagerService
return;
}
}
- }.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
+ };
+ mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
// Cancel account request notification if an app op was preventing the account access
for (int i = 0; i < INTERESTING_APP_OPS.length; ++i) {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 13d367a95942..336a35e7a7e3 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -3433,8 +3433,12 @@ public class OomAdjuster {
// Process has user visible activities.
return PROCESS_CAPABILITY_CPU_TIME;
}
- if (app.mServices.hasUndemotedShortForegroundService(nowUptime)) {
- // It running a short fgs, just give it cpu time.
+ if (Flags.prototypeAggressiveFreezing()) {
+ if (app.mServices.hasUndemotedShortForegroundService(nowUptime)) {
+ // Grant cpu time for short FGS even when aggressively freezing.
+ return PROCESS_CAPABILITY_CPU_TIME;
+ }
+ } else if (app.mServices.hasForegroundServices()) {
return PROCESS_CAPABILITY_CPU_TIME;
}
if (app.mReceivers.numberOfCurReceivers() > 0) {
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 2c0366e6a6db..ac30be99979e 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -31,7 +31,6 @@ import static android.os.Process.SYSTEM_UID;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.window.flags.Flags.balClearAllowlistDuration;
import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -330,7 +329,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
mAllowBgActivityStartsForActivitySender.remove(token);
mAllowBgActivityStartsForBroadcastSender.remove(token);
mAllowBgActivityStartsForServiceSender.remove(token);
- if (mAllowlistDuration != null && balClearAllowlistDuration()) {
+ if (mAllowlistDuration != null) {
TempAllowListDuration duration = mAllowlistDuration.get(token);
if (duration != null
&& duration.type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 1503d889c298..eea667ef2f39 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1443,17 +1443,32 @@ class ProcessRecord implements WindowProcessListener {
void onProcessFrozen() {
mProfile.onProcessFrozen();
- if (mThread != null) mThread.onProcessPaused();
+ final ApplicationThreadDeferred t;
+ synchronized (mService) {
+ t = mThread;
+ }
+ // Release the lock before calling the notifier, in case that calls back into AM.
+ if (t != null) t.onProcessPaused();
}
void onProcessUnfrozen() {
- if (mThread != null) mThread.onProcessUnpaused();
+ final ApplicationThreadDeferred t;
+ synchronized (mService) {
+ t = mThread;
+ }
+ // Release the lock before calling the notifier, in case that calls back into AM.
+ if (t != null) t.onProcessUnpaused();
mProfile.onProcessUnfrozen();
mServices.onProcessUnfrozen();
}
void onProcessFrozenCancelled() {
- if (mThread != null) mThread.onProcessPausedCancelled();
+ final ApplicationThreadDeferred t;
+ synchronized (mService) {
+ t = mThread;
+ }
+ // Release the lock before calling the notifier, in case that calls back into AM.
+ if (t != null) t.onProcessPausedCancelled();
mServices.onProcessFrozenCancelled();
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 3a041fd3b38a..cfd22fbdeece 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -187,10 +187,12 @@ public class SettingsToPropertiesMapper {
"crumpet",
"dck_framework",
"desktop_apps",
+ "desktop_audio",
"desktop_better_together",
"desktop_bsp",
"desktop_camera",
"desktop_connectivity",
+ "desktop_dev_experience",
"desktop_display",
"desktop_commercial",
"desktop_firmware",
@@ -199,10 +201,14 @@ public class SettingsToPropertiesMapper {
"desktop_input",
"desktop_kernel",
"desktop_ml",
+ "desktop_networking",
"desktop_serviceability",
"desktop_oobe",
"desktop_peripherals",
+ "desktop_personalization",
"desktop_pnp",
+ "desktop_privacy",
+ "desktop_release",
"desktop_security",
"desktop_stats",
"desktop_sysui",
diff --git a/services/core/java/com/android/server/appop/AttributedOp.java b/services/core/java/com/android/server/appop/AttributedOp.java
index 9dd09cef88f9..40085ed89294 100644
--- a/services/core/java/com/android/server/appop/AttributedOp.java
+++ b/services/core/java/com/android/server/appop/AttributedOp.java
@@ -113,7 +113,7 @@ final class AttributedOp {
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, uidState, flags, accessTime,
AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE,
- DiscreteOpsRegistry.ACCESS_TYPE_NOTE_OP, accessCount);
+ accessCount);
}
/**
@@ -257,8 +257,7 @@ final class AttributedOp {
if (isStarted) {
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, uidState, flags, startTime,
- attributionFlags, attributionChainId,
- DiscreteOpsRegistry.ACCESS_TYPE_START_OP, 1);
+ attributionFlags, attributionChainId, 1);
}
}
@@ -344,9 +343,7 @@ final class AttributedOp {
mAppOpsService.mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, event.getUidState(),
event.getFlags(), finishedEvent.getNoteTime(), finishedEvent.getDuration(),
- event.getAttributionFlags(), event.getAttributionChainId(),
- isPausing ? DiscreteOpsRegistry.ACCESS_TYPE_PAUSE_OP
- : DiscreteOpsRegistry.ACCESS_TYPE_FINISH_OP);
+ event.getAttributionFlags(), event.getAttributionChainId());
if (!isPausing) {
mAppOpsService.mInProgressStartOpEventPool.release(event);
@@ -454,7 +451,7 @@ final class AttributedOp {
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, event.getUidState(),
event.getFlags(), startTime, event.getAttributionFlags(),
- event.getAttributionChainId(), DiscreteOpsRegistry.ACCESS_TYPE_RESUME_OP, 1);
+ event.getAttributionChainId(), 1);
if (shouldSendActive) {
mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid,
parent.packageName, tag, event.getVirtualDeviceId(), true,
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
index 12c35ae92cbe..b7599f6e40c3 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
@@ -46,22 +46,17 @@ import static android.app.AppOpsManager.OP_WRITE_SMS;
import static java.lang.Long.min;
import static java.lang.Math.max;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.os.AsyncTask;
import android.os.Build;
-import android.permission.flags.Flags;
import android.provider.DeviceConfig;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FrameworkStatsLog;
import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
@@ -134,27 +129,6 @@ abstract class DiscreteOpsRegistry {
boolean mDebugMode = false;
- static final int ACCESS_TYPE_NOTE_OP =
- FrameworkStatsLog.APP_OP_ACCESS_TRACKED__ACCESS_TYPE__NOTE_OP;
- static final int ACCESS_TYPE_START_OP =
- FrameworkStatsLog.APP_OP_ACCESS_TRACKED__ACCESS_TYPE__START_OP;
- static final int ACCESS_TYPE_FINISH_OP =
- FrameworkStatsLog.APP_OP_ACCESS_TRACKED__ACCESS_TYPE__FINISH_OP;
- static final int ACCESS_TYPE_PAUSE_OP =
- FrameworkStatsLog.APP_OP_ACCESS_TRACKED__ACCESS_TYPE__PAUSE_OP;
- static final int ACCESS_TYPE_RESUME_OP =
- FrameworkStatsLog.APP_OP_ACCESS_TRACKED__ACCESS_TYPE__RESUME_OP;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"ACCESS_TYPE_"}, value = {
- ACCESS_TYPE_NOTE_OP,
- ACCESS_TYPE_START_OP,
- ACCESS_TYPE_FINISH_OP,
- ACCESS_TYPE_PAUSE_OP,
- ACCESS_TYPE_RESUME_OP
- })
- @interface AccessType {}
-
void systemReady() {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
AsyncTask.THREAD_POOL_EXECUTOR, (DeviceConfig.Properties p) -> {
@@ -166,8 +140,7 @@ abstract class DiscreteOpsRegistry {
abstract void recordDiscreteAccess(int uid, String packageName, @NonNull String deviceId,
int op, @Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
@AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
- @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
- @DiscreteOpsRegistry.AccessType int accessType);
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId);
/**
* A periodic callback from {@link AppOpsService} to flush the in memory events to disk.
@@ -227,9 +200,6 @@ abstract class DiscreteOpsRegistry {
return true;
}
- // could this be impl detail of discrete registry, just one test is using the method
- // abstract DiscreteRegistry.DiscreteOps getAllDiscreteOps();
-
private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_CUTOFF)) {
sDiscreteHistoryCutoff = p.getLong(PROPERTY_DISCRETE_HISTORY_CUTOFF,
@@ -277,28 +247,4 @@ abstract class DiscreteOpsRegistry {
}
return result;
}
-
- /**
- * Whether app op access tacking is enabled and a metric event should be logged.
- */
- static boolean shouldLogAccess(int op) {
- return Flags.appopAccessTrackingLoggingEnabled()
- && ArrayUtils.contains(sDiscreteOpsToLog, op);
- }
-
- String getAttributionTag(String attributionTag, String packageName) {
- if (attributionTag == null || packageName == null) {
- return attributionTag;
- }
- int firstChar = 0;
- if (attributionTag.startsWith(packageName)) {
- firstChar = packageName.length();
- if (firstChar < attributionTag.length() && attributionTag.charAt(firstChar)
- == '.') {
- firstChar++;
- }
- }
- return attributionTag.substring(firstChar);
- }
-
}
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
index dc11be9aadb6..c897891d02c3 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
@@ -36,7 +36,6 @@ import android.util.IntArray;
import android.util.LongSparseArray;
import android.util.Slog;
-import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ServiceThread;
import java.io.File;
@@ -97,15 +96,7 @@ public class DiscreteOpsSqlRegistry extends DiscreteOpsRegistry {
void recordDiscreteAccess(int uid, String packageName,
@NonNull String deviceId, int op,
@Nullable String attributionTag, int flags, int uidState,
- long accessTime, long accessDuration, int attributionFlags, int attributionChainId,
- int accessType) {
- if (shouldLogAccess(op)) {
- FrameworkStatsLog.write(FrameworkStatsLog.APP_OP_ACCESS_TRACKED, uid, op, accessType,
- uidState, flags, attributionFlags,
- getAttributionTag(attributionTag, packageName),
- attributionChainId);
- }
-
+ long accessTime, long accessDuration, int attributionFlags, int attributionChainId) {
if (!isDiscreteOp(op, flags)) {
return;
}
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsTestingShim.java b/services/core/java/com/android/server/appop/DiscreteOpsTestingShim.java
index 1523cca86607..909a04c44ae5 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsTestingShim.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsTestingShim.java
@@ -48,15 +48,13 @@ class DiscreteOpsTestingShim extends DiscreteOpsRegistry {
@Override
void recordDiscreteAccess(int uid, String packageName, @NonNull String deviceId, int op,
@Nullable String attributionTag, int flags, int uidState, long accessTime,
- long accessDuration, int attributionFlags, int attributionChainId, int accessType) {
+ long accessDuration, int attributionFlags, int attributionChainId) {
long start = SystemClock.uptimeMillis();
mXmlRegistry.recordDiscreteAccess(uid, packageName, deviceId, op, attributionTag, flags,
- uidState, accessTime, accessDuration, attributionFlags, attributionChainId,
- accessType);
+ uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
long start2 = SystemClock.uptimeMillis();
mSqlRegistry.recordDiscreteAccess(uid, packageName, deviceId, op, attributionTag, flags,
- uidState, accessTime, accessDuration, attributionFlags, attributionChainId,
- accessType);
+ uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
long end = SystemClock.uptimeMillis();
long xmlTimeTaken = start2 - start;
long sqlTimeTaken = end - start2;
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
index a6e3fc7cc66a..20706b659ffb 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
@@ -45,7 +45,6 @@ import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -159,15 +158,7 @@ class DiscreteOpsXmlRegistry extends DiscreteOpsRegistry {
void recordDiscreteAccess(int uid, String packageName, @NonNull String deviceId, int op,
@Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
@AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
- @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
- @AccessType int accessType) {
- if (shouldLogAccess(op)) {
- FrameworkStatsLog.write(FrameworkStatsLog.APP_OP_ACCESS_TRACKED, uid, op, accessType,
- uidState, flags, attributionFlags,
- getAttributionTag(attributionTag, packageName),
- attributionChainId);
- }
-
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
if (!isDiscreteOp(op, flags)) {
return;
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index d267e0d9e536..06e43e8ec68d 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -497,7 +497,7 @@ final class HistoricalRegistry {
@NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
@OpFlags int flags, long accessTime,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
- @DiscreteOpsRegistry.AccessType int accessType, int accessCount) {
+ int accessCount) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) {
@@ -510,7 +510,7 @@ final class HistoricalRegistry {
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op,
attributionTag, flags, uidState, accessTime, -1, attributionFlags,
- attributionChainId, accessType);
+ attributionChainId);
}
}
}
@@ -533,8 +533,7 @@ final class HistoricalRegistry {
void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
@NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
@OpFlags int flags, long eventStartTime, long increment,
- @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
- @DiscreteOpsRegistry.AccessType int accessType) {
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) {
@@ -546,7 +545,7 @@ final class HistoricalRegistry {
attributionTag, uidState, flags, increment);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op,
attributionTag, flags, uidState, eventStartTime, increment,
- attributionFlags, attributionChainId, accessType);
+ attributionFlags, attributionChainId);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 8ef79a916530..4b5f06b13885 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1472,8 +1472,8 @@ public class AudioDeviceBroker {
mAudioService.postAccessoryPlugMediaUnmute(device);
}
- /*package*/ int getVssVolumeForDevice(int streamType, int device) {
- return mAudioService.getVssVolumeForDevice(streamType, device);
+ /*package*/ int getVolumeForDeviceIgnoreMute(int streamType, int device) {
+ return mAudioService.getVolumeForDeviceIgnoreMute(streamType, device);
}
/*package*/ int getMaxVssVolumeForStream(int streamType) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 829d9ea7495f..2e6d98485e85 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -2482,7 +2482,7 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeHearingAidDeviceAvailable(
String address, String name, int streamType, String eventSource) {
- final int hearingAidVolIndex = mDeviceBroker.getVssVolumeForDevice(streamType,
+ final int hearingAidVolIndex = mDeviceBroker.getVolumeForDeviceIgnoreMute(streamType,
DEVICE_OUT_HEARING_AID);
mDeviceBroker.postSetHearingAidVolumeIndex(hearingAidVolIndex, streamType);
@@ -2672,7 +2672,7 @@ public class AudioDeviceInventory {
}
final int leAudioVolIndex = (volumeIndex == -1)
- ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
+ ? mDeviceBroker.getVolumeForDeviceIgnoreMute(streamType, device)
: volumeIndex;
final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ada1cd73f775..a43e4d98c077 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -529,7 +529,7 @@ public class AudioService extends IAudioService.Stub
*/
private InputDeviceVolumeHelper mInputDeviceVolumeHelper;
- /*package*/ int getVssVolumeForDevice(int stream, int device) {
+ /*package*/ int getVolumeForDeviceIgnoreMute(int stream, int device) {
final VolumeStreamState streamState = mStreamStates.get(stream);
return streamState != null ? streamState.getIndex(device) : -1;
}
@@ -5098,7 +5098,7 @@ public class AudioService extends IAudioService.Stub
}
final int device = absVolumeDevices.toArray(new Integer[0])[0].intValue();
- final int index = getStreamVolume(streamType, device);
+ final int index = getVolumeForDeviceIgnoreMute(streamType, device);
if (DEBUG_VOL) {
Slog.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 643f3308d8f5..67afff79dffd 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -724,7 +724,7 @@ public class SoundDoseHelper {
int device = mAudioService.getDeviceForStream(AudioSystem.STREAM_MUSIC);
if (safeDevicesContains(device) && isStreamActive) {
scheduleMusicActiveCheck();
- int index = mAudioService.getVssVolumeForDevice(AudioSystem.STREAM_MUSIC,
+ int index = mAudioService.getVolumeForDeviceIgnoreMute(AudioSystem.STREAM_MUSIC,
device);
if (index > safeMediaVolumeIndex(device)) {
// Approximate cumulative active music time
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 969a684f6ef5..2d387ea38df5 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -261,6 +261,7 @@ public class SyncManager {
private final SyncLogger mLogger;
private final AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper;
+ private final PackageMonitorImpl mPackageMonitor;
private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
for (int i = 0, size = pendingJobs.size(); i < size; i++) {
@@ -725,8 +726,8 @@ public class SyncManager {
mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
- final PackageMonitor packageMonitor = new PackageMonitorImpl();
- packageMonitor.register(mContext, null /* thread */, UserHandle.ALL,
+ mPackageMonitor = new PackageMonitorImpl();
+ mPackageMonitor.register(mContext, null /* thread */, UserHandle.ALL,
false /* externalStorage */);
intentFilter = new IntentFilter(Intent.ACTION_TIME_CHANGED);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d402f010281f..a28069bbf050 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -674,9 +674,9 @@ public final class DisplayManagerService extends SystemService {
mConfigParameterProvider = new DeviceConfigParameterProvider(DeviceConfigInterface.REAL);
mExtraDisplayLoggingPackageName = DisplayProperties.debug_vri_package().orElse(null);
mExtraDisplayEventLogging = !TextUtils.isEmpty(mExtraDisplayLoggingPackageName);
-
+ // TODO(b/400384229): stats service needs to react to mirror-extended switch
mExternalDisplayStatsService = new ExternalDisplayStatsService(mContext, mHandler,
- this::isExtendedDisplayEnabled);
+ this::isExtendedDisplayAllowed);
mDisplayNotificationManager = new DisplayNotificationManager(mFlags, mContext,
mExternalDisplayStatsService);
mExternalDisplayPolicy = new ExternalDisplayPolicy(new ExternalDisplayPolicyInjector());
@@ -690,7 +690,7 @@ public final class DisplayManagerService extends SystemService {
deliverTopologyUpdate(update.first);
};
mDisplayTopologyCoordinator = new DisplayTopologyCoordinator(
- this::isExtendedDisplayEnabled, topologyChangedCallback,
+ this::isExtendedDisplayAllowed, topologyChangedCallback,
new HandlerExecutor(mHandler), mSyncRoot, backupManager::dataChanged);
} else {
mDisplayTopologyCoordinator = null;
@@ -2411,7 +2411,10 @@ public final class DisplayManagerService extends SystemService {
updateLogicalDisplayState(display);
}
- private boolean isExtendedDisplayEnabled() {
+ private boolean isExtendedDisplayAllowed() {
+ if (mFlags.isDisplayContentModeManagementEnabled()) {
+ return true;
+ }
try {
return 0 != Settings.Global.getInt(
mContext.getContentResolver(),
@@ -2442,7 +2445,10 @@ public final class DisplayManagerService extends SystemService {
applyDisplayChangedLocked(display);
}
- if (mDisplayTopologyCoordinator != null) {
+ // The default display should always be added to the topology. Other displays will be added
+ // upon calling onDisplayBelongToTopologyChanged().
+ if (mDisplayTopologyCoordinator != null
+ && display.getDisplayIdLocked() == Display.DEFAULT_DISPLAY) {
mDisplayTopologyCoordinator.onDisplayAdded(display.getDisplayInfoLocked());
}
}
@@ -6037,6 +6043,24 @@ public final class DisplayManagerService extends SystemService {
}
@Override
+ public void onDisplayBelongToTopologyChanged(int displayId, boolean inTopology) {
+ if (mDisplayTopologyCoordinator == null) {
+ return;
+ }
+ if (inTopology) {
+ var info = getDisplayInfo(displayId);
+ if (info == null) {
+ Slog.w(TAG, "onDisplayBelongToTopologyChanged: cancelled displayId="
+ + displayId + " info=null");
+ return;
+ }
+ mDisplayTopologyCoordinator.onDisplayAdded(info);
+ } else {
+ mDisplayTopologyCoordinator.onDisplayRemoved(displayId);
+ }
+ }
+
+ @Override
public void reloadTopologies(final int userId) {
// Reload topologies only if the userId matches the current user id.
if (userId == mCurrentUserId) {
diff --git a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
index 2618cf40d113..b4df1f76dccb 100644
--- a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
+++ b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
@@ -69,9 +69,9 @@ class DisplayTopologyCoordinator {
private final SparseArray<String> mDisplayIdToUniqueIdMapping = new SparseArray<>();
/**
- * Check if extended displays are enabled. If not, a topology is not needed.
+ * Check if extended displays are allowed. If not, a topology is not needed.
*/
- private final BooleanSupplier mIsExtendedDisplayEnabled;
+ private final BooleanSupplier mIsExtendedDisplayAllowed;
/**
* Callback used to send topology updates.
@@ -83,21 +83,21 @@ class DisplayTopologyCoordinator {
private final DisplayManagerService.SyncRoot mSyncRoot;
private final Runnable mTopologySavedCallback;
- DisplayTopologyCoordinator(BooleanSupplier isExtendedDisplayEnabled,
+ DisplayTopologyCoordinator(BooleanSupplier isExtendedDisplayAllowed,
Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> onTopologyChangedCallback,
Executor topologyChangeExecutor, DisplayManagerService.SyncRoot syncRoot,
Runnable topologySavedCallback) {
- this(new Injector(), isExtendedDisplayEnabled, onTopologyChangedCallback,
+ this(new Injector(), isExtendedDisplayAllowed, onTopologyChangedCallback,
topologyChangeExecutor, syncRoot, topologySavedCallback);
}
@VisibleForTesting
- DisplayTopologyCoordinator(Injector injector, BooleanSupplier isExtendedDisplayEnabled,
+ DisplayTopologyCoordinator(Injector injector, BooleanSupplier isExtendedDisplayAllowed,
Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> onTopologyChangedCallback,
Executor topologyChangeExecutor, DisplayManagerService.SyncRoot syncRoot,
Runnable topologySavedCallback) {
mTopology = injector.getTopology();
- mIsExtendedDisplayEnabled = isExtendedDisplayEnabled;
+ mIsExtendedDisplayAllowed = isExtendedDisplayAllowed;
mOnTopologyChangedCallback = onTopologyChangedCallback;
mTopologyChangeExecutor = topologyChangeExecutor;
mSyncRoot = syncRoot;
@@ -262,14 +262,9 @@ class DisplayTopologyCoordinator {
return false;
}
if ((info.type == Display.TYPE_EXTERNAL || info.type == Display.TYPE_OVERLAY)
- && !mIsExtendedDisplayEnabled.getAsBoolean()) {
+ && !mIsExtendedDisplayAllowed.getAsBoolean()) {
Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
- + "type is EXTERNAL or OVERLAY and !mIsExtendedDisplayEnabled");
- return false;
- }
- if (info.displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
- Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
- + "it is not in the default display group");
+ + "type is EXTERNAL or OVERLAY and !mIsExtendedDisplayAllowed");
return false;
}
return true;
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 6e5e0fd5224f..af065861f1ae 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -193,6 +193,8 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
@Nullable
private UserManagerInternal mUm;
+ private final MyPackageMonitor mPackageMonitor;
+
/**
* Default constructor.
*
@@ -289,6 +291,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
});
}
+ mPackageMonitor = new MyPackageMonitor(/* supportsPackageRestartQuery */ true);
startTrackingPackageChanges();
}
@@ -986,260 +989,264 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
}
- private void startTrackingPackageChanges() {
- final PackageMonitor monitor = new PackageMonitor(true) {
+ private class MyPackageMonitor extends PackageMonitor {
+ MyPackageMonitor(boolean supportsPackageRestartQuery) {
+ super(supportsPackageRestartQuery);
+ }
- @Override
- public void onPackageUpdateStarted(@NonNull String packageName, int uid) {
- if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName);
+ @Override
+ public void onPackageUpdateStarted(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName);
+ synchronized (mLock) {
final String activePackageName = getActiveServicePackageNameLocked();
if (!packageName.equals(activePackageName)) return;
final int userId = getChangingUserId();
- synchronized (mLock) {
- if (mUpdatingPackageNames == null) {
- mUpdatingPackageNames = new SparseArray<String>(mServicesCacheList.size());
+
+ if (mUpdatingPackageNames == null) {
+ mUpdatingPackageNames = new SparseArray<String>(mServicesCacheList.size());
+ }
+ mUpdatingPackageNames.put(userId, packageName);
+ onServicePackageUpdatingLocked(userId);
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
}
- mUpdatingPackageNames.put(userId, packageName);
- onServicePackageUpdatingLocked(userId);
- if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId + " while package "
- + activePackageName + " is being updated");
- }
- } else {
- if (debug) {
- Slog.d(mTag, "Removing service for user " + userId
- + " because package " + activePackageName
- + " is being updated");
- }
- removeCachedServiceListLocked(userId);
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId
+ + " because package " + activePackageName
+ + " is being updated");
+ }
+ removeCachedServiceListLocked(userId);
- if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
- != 0) {
- if (debug) {
- Slog.d(mTag, "Eagerly recreating service for user "
- + userId);
- }
- getServiceForUserLocked(userId);
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
+ != 0) {
+ if (debug) {
+ Slog.d(mTag, "Eagerly recreating service for user "
+ + userId);
}
+ getServiceForUserLocked(userId);
}
}
}
+ }
- @Override
- public void onPackageUpdateFinished(@NonNull String packageName, int uid) {
- if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName);
- final int userId = getChangingUserId();
- synchronized (mLock) {
- final String activePackageName = mUpdatingPackageNames == null ? null
- : mUpdatingPackageNames.get(userId);
- if (packageName.equals(activePackageName)) {
- if (mUpdatingPackageNames != null) {
- mUpdatingPackageNames.remove(userId);
- if (mUpdatingPackageNames.size() == 0) {
- mUpdatingPackageNames = null;
- }
+ @Override
+ public void onPackageUpdateFinished(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName);
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final String activePackageName = mUpdatingPackageNames == null ? null
+ : mUpdatingPackageNames.get(userId);
+ if (packageName.equals(activePackageName)) {
+ if (mUpdatingPackageNames != null) {
+ mUpdatingPackageNames.remove(userId);
+ if (mUpdatingPackageNames.size() == 0) {
+ mUpdatingPackageNames = null;
}
- onServicePackageUpdatedLocked(userId);
- } else {
- handlePackageUpdateLocked(packageName);
}
+ onServicePackageUpdatedLocked(userId);
+ } else {
+ handlePackageUpdateLocked(packageName);
}
}
+ }
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- if (mServiceNameResolver != null
- && mServiceNameResolver.isConfiguredInMultipleMode()) {
- final int userId = getChangingUserId();
- synchronized (mLock) {
- handlePackageRemovedMultiModeLocked(packageName, userId);
- }
- return;
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ if (mServiceNameResolver != null
+ && mServiceNameResolver.isConfiguredInMultipleMode()) {
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ handlePackageRemovedMultiModeLocked(packageName, userId);
}
+ return;
+ }
- synchronized (mLock) {
- final int userId = getChangingUserId();
- final S service = peekServiceForUserLocked(userId);
- if (service != null) {
- final ComponentName componentName = service.getServiceComponentName();
- if (componentName != null) {
- if (packageName.equals(componentName.getPackageName())) {
- handleActiveServiceRemoved(userId);
- }
+ synchronized (mLock) {
+ final int userId = getChangingUserId();
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ handleActiveServiceRemoved(userId);
}
}
}
}
+ }
- @Override
- public boolean onHandleForceStop(Intent intent, String[] packages,
- int uid, boolean doit) {
- synchronized (mLock) {
- final String activePackageName = getActiveServicePackageNameLocked();
- for (String pkg : packages) {
- if (pkg.equals(activePackageName)) {
- if (!doit) {
- return true;
- }
- final String action = intent.getAction();
- final int userId = getChangingUserId();
- if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
- handleActiveServiceRestartedLocked(activePackageName, userId);
- } else {
- removeCachedServiceListLocked(userId);
- }
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] packages,
+ int uid, boolean doit) {
+ synchronized (mLock) {
+ final String activePackageName = getActiveServicePackageNameLocked();
+ for (String pkg : packages) {
+ if (pkg.equals(activePackageName)) {
+ if (!doit) {
+ return true;
+ }
+ final String action = intent.getAction();
+ final int userId = getChangingUserId();
+ if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+ handleActiveServiceRestartedLocked(activePackageName, userId);
} else {
- handlePackageUpdateLocked(pkg);
+ removeCachedServiceListLocked(userId);
}
+ } else {
+ handlePackageUpdateLocked(pkg);
}
}
- return false;
}
+ return false;
+ }
- @Override
- public void onPackageDataCleared(String packageName, int uid) {
- if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
- final int userId = getChangingUserId();
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
+ final int userId = getChangingUserId();
- if (mServiceNameResolver != null
- && mServiceNameResolver.isConfiguredInMultipleMode()) {
- synchronized (mLock) {
- onServicePackageDataClearedMultiModeLocked(packageName, userId);
- }
- return;
+ if (mServiceNameResolver != null
+ && mServiceNameResolver.isConfiguredInMultipleMode()) {
+ synchronized (mLock) {
+ onServicePackageDataClearedMultiModeLocked(packageName, userId);
}
+ return;
+ }
- synchronized (mLock) {
- final S service = peekServiceForUserLocked(userId);
- if (service != null) {
- final ComponentName componentName = service.getServiceComponentName();
- if (componentName != null) {
- if (packageName.equals(componentName.getPackageName())) {
- onServicePackageDataClearedLocked(userId);
- }
+ synchronized (mLock) {
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ onServicePackageDataClearedLocked(userId);
}
}
}
}
+ }
- private void handleActiveServiceRemoved(@UserIdInt int userId) {
- synchronized (mLock) {
- removeCachedServiceListLocked(userId);
+ private void handleActiveServiceRemoved(@UserIdInt int userId) {
+ synchronized (mLock) {
+ removeCachedServiceListLocked(userId);
+ }
+ final String serviceSettingsProperty = getServiceSettingsProperty();
+ if (serviceSettingsProperty != null) {
+ Settings.Secure.putStringForUser(getContext().getContentResolver(),
+ serviceSettingsProperty, null, userId);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void handleActiveServiceRestartedLocked(String activePackageName,
+ @UserIdInt int userId) {
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being restarted");
}
- final String serviceSettingsProperty = getServiceSettingsProperty();
- if (serviceSettingsProperty != null) {
- Settings.Secure.putStringForUser(getContext().getContentResolver(),
- serviceSettingsProperty, null, userId);
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId
+ + " because package " + activePackageName
+ + " is being restarted");
}
- }
+ removeCachedServiceListLocked(userId);
- @GuardedBy("mLock")
- private void handleActiveServiceRestartedLocked(String activePackageName,
- @UserIdInt int userId) {
- if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
if (debug) {
- Slog.d(mTag, "Holding service for user " + userId + " while package "
- + activePackageName + " is being restarted");
- }
- } else {
- if (debug) {
- Slog.d(mTag, "Removing service for user " + userId
- + " because package " + activePackageName
- + " is being restarted");
- }
- removeCachedServiceListLocked(userId);
-
- if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
- if (debug) {
- Slog.d(mTag, "Eagerly recreating service for user " + userId);
- }
- updateCachedServiceLocked(userId);
+ Slog.d(mTag, "Eagerly recreating service for user " + userId);
}
+ updateCachedServiceLocked(userId);
}
- onServicePackageRestartedLocked(userId);
}
+ onServicePackageRestartedLocked(userId);
+ }
- @Override
- public void onPackageModified(String packageName) {
- synchronized (mLock) {
- if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
+ @Override
+ public void onPackageModified(String packageName) {
+ synchronized (mLock) {
+ if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
- if (mServiceNameResolver == null) {
- return;
- }
+ if (mServiceNameResolver == null) {
+ return;
+ }
- final int userId = getChangingUserId();
- final String[] serviceNames = mServiceNameResolver.getDefaultServiceNameList(
- userId);
- if (serviceNames != null) {
- if (Flags.packageUpdateFixEnabled()) {
- if (mServiceNameResolver.isConfiguredInMultipleMode()) {
- // Remove any service that is in the cache but is no longer valid
- // after this modification for this particular package
- removeInvalidCachedServicesLocked(serviceNames, packageName,
- userId);
- }
+ final int userId = getChangingUserId();
+ final String[] serviceNames = mServiceNameResolver.getDefaultServiceNameList(
+ userId);
+ if (serviceNames != null) {
+ if (Flags.packageUpdateFixEnabled()) {
+ if (mServiceNameResolver.isConfiguredInMultipleMode()) {
+ // Remove any service that is in the cache but is no longer valid
+ // after this modification for this particular package
+ removeInvalidCachedServicesLocked(serviceNames, packageName,
+ userId);
}
+ }
- // Update services that are still valid
- for (int i = 0; i < serviceNames.length; i++) {
- peekAndUpdateCachedServiceLocked(packageName, userId,
- serviceNames[i]);
- }
+ // Update services that are still valid
+ for (int i = 0; i < serviceNames.length; i++) {
+ peekAndUpdateCachedServiceLocked(packageName, userId,
+ serviceNames[i]);
}
}
}
+ }
- @GuardedBy("mLock")
- private void peekAndUpdateCachedServiceLocked(String packageName, int userId,
- String serviceName) {
- if (serviceName == null) {
- return;
- }
-
- final ComponentName serviceComponentName =
- ComponentName.unflattenFromString(serviceName);
- if (serviceComponentName == null
- || !serviceComponentName.getPackageName().equals(packageName)) {
- return;
- }
+ @GuardedBy("mLock")
+ private void peekAndUpdateCachedServiceLocked(String packageName, int userId,
+ String serviceName) {
+ if (serviceName == null) {
+ return;
+ }
- // The default service package has changed, update the cached if the service
- // exists but no active component.
- final S service = peekServiceForUserLocked(userId);
- if (service != null) {
- final ComponentName componentName = service.getServiceComponentName();
- if (componentName == null) {
- if (verbose) Slog.v(mTag, "update cached");
- updateCachedServiceLocked(userId);
- }
- }
+ final ComponentName serviceComponentName =
+ ComponentName.unflattenFromString(serviceName);
+ if (serviceComponentName == null
+ || !serviceComponentName.getPackageName().equals(packageName)) {
+ return;
}
- @GuardedBy("mLock")
- private String getActiveServicePackageNameLocked() {
- final int userId = getChangingUserId();
- final S service = peekServiceForUserLocked(userId);
- if (service == null) {
- return null;
- }
- final ComponentName serviceComponent = service.getServiceComponentName();
- if (serviceComponent == null) {
- return null;
+ // The default service package has changed, update the cached if the service
+ // exists but no active component.
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName == null) {
+ if (verbose) Slog.v(mTag, "update cached");
+ updateCachedServiceLocked(userId);
}
- return serviceComponent.getPackageName();
}
+ }
- @GuardedBy("mLock")
- private void handlePackageUpdateLocked(String packageName) {
- visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName));
+ @GuardedBy("mLock")
+ private String getActiveServicePackageNameLocked() {
+ final int userId = getChangingUserId();
+ final S service = peekServiceForUserLocked(userId);
+ if (service == null) {
+ return null;
+ }
+ final ComponentName serviceComponent = service.getServiceComponentName();
+ if (serviceComponent == null) {
+ return null;
}
- };
+ return serviceComponent.getPackageName();
+ }
+ @GuardedBy("mLock")
+ private void handlePackageUpdateLocked(String packageName) {
+ visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName));
+ }
+ }
+
+ private void startTrackingPackageChanges() {
// package changes
- monitor.register(getContext(), null, UserHandle.ALL, true);
+ mPackageMonitor.register(getContext(), null, UserHandle.ALL, true);
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/input/InputGestureManager.java b/services/core/java/com/android/server/input/InputGestureManager.java
index 7f853844c326..67e1ccc6a850 100644
--- a/services/core/java/com/android/server/input/InputGestureManager.java
+++ b/services/core/java/com/android/server/input/InputGestureManager.java
@@ -138,11 +138,6 @@ final class InputGestureManager {
KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT
),
createKeyGesture(
- KeyEvent.KEYCODE_DEL,
- KeyEvent.META_META_ON,
- KeyGestureEvent.KEY_GESTURE_TYPE_BACK
- ),
- createKeyGesture(
KeyEvent.KEYCODE_ESCAPE,
KeyEvent.META_META_ON,
KeyGestureEvent.KEY_GESTURE_TYPE_BACK
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index af726bd28718..68ad8f7e9433 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2902,12 +2902,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final long ident = Binder.clearCallingIdentity();
try {
if (windowPerceptible != null && !windowPerceptible) {
- if ((vis & InputMethodService.IME_VISIBLE) != 0) {
- vis &= ~InputMethodService.IME_VISIBLE;
- vis |= InputMethodService.IME_VISIBLE_IMPERCEPTIBLE;
- }
- } else {
- vis &= ~InputMethodService.IME_VISIBLE_IMPERCEPTIBLE;
+ vis &= ~InputMethodService.IME_VISIBLE;
}
final var curId = bindingController.getCurId();
// TODO(b/305849394): Make mMenuController multi-user aware.
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
index f40d0dd18213..2d937bdcc683 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
@@ -16,6 +16,8 @@
package com.android.server.location.contexthub;
+import static com.android.server.location.contexthub.ContextHubTransactionManager.RELIABLE_MESSAGE_DUPLICATE_DETECTION_TIMEOUT;
+
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
@@ -44,6 +46,9 @@ import com.android.internal.annotations.GuardedBy;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
@@ -100,7 +105,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
private final Object mOpenSessionLock = new Object();
- static class SessionInfo {
+ static class Session {
enum SessionState {
/* The session is pending acceptance from the remote endpoint. */
PENDING,
@@ -119,7 +124,15 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
*/
private final Set<Integer> mPendingSequenceNumbers = new HashSet<>();
- SessionInfo(HubEndpointInfo remoteEndpointInfo, boolean remoteInitiated) {
+ /**
+ * Stores the history of received messages that are timestamped. We use a LinkedHashMap to
+ * guarantee insertion ordering for easier manipulation of removing expired entries.
+ *
+ * <p>The key is the sequence number, and the value is the timestamp in milliseconds.
+ */
+ private final LinkedHashMap<Integer, Long> mRxMessageHistoryMap = new LinkedHashMap<>();
+
+ Session(HubEndpointInfo remoteEndpointInfo, boolean remoteInitiated) {
mRemoteEndpointInfo = remoteEndpointInfo;
mRemoteInitiated = remoteInitiated;
}
@@ -157,11 +170,43 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
consumer.accept(sequenceNumber);
}
}
+
+ public boolean isInMessageHistory(HubMessage message) {
+ // Clean up the history
+ Iterator<Map.Entry<Integer, Long>> iterator =
+ mRxMessageHistoryMap.entrySet().iterator();
+ long nowMillis = System.currentTimeMillis();
+ while (iterator.hasNext()) {
+ Map.Entry<Integer, Long> nextEntry = iterator.next();
+ long expiryMillis = RELIABLE_MESSAGE_DUPLICATE_DETECTION_TIMEOUT.toMillis();
+ if (nowMillis >= nextEntry.getValue() + expiryMillis) {
+ iterator.remove();
+ }
+ break;
+ }
+
+ return mRxMessageHistoryMap.containsKey(message.getMessageSequenceNumber());
+ }
+
+ public void addMessageToHistory(HubMessage message) {
+ if (mRxMessageHistoryMap.containsKey(message.getMessageSequenceNumber())) {
+ long value = mRxMessageHistoryMap.get(message.getMessageSequenceNumber());
+ Log.w(
+ TAG,
+ "Message already exists in history (inserted @ "
+ + value
+ + " ms): "
+ + message);
+ return;
+ }
+ mRxMessageHistoryMap.put(
+ message.getMessageSequenceNumber(), System.currentTimeMillis());
+ }
}
/** A map between a session ID which maps to its current state. */
@GuardedBy("mOpenSessionLock")
- private final SparseArray<SessionInfo> mSessionInfoMap = new SparseArray<>();
+ private final SparseArray<Session> mSessionMap = new SparseArray<>();
/** The package name of the app that created the endpoint */
private final String mPackageName;
@@ -232,7 +277,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
synchronized (mOpenSessionLock) {
try {
- mSessionInfoMap.put(sessionId, new SessionInfo(destination, false));
+ mSessionMap.put(sessionId, new Session(destination, false));
mHubInterface.openEndpointSession(
sessionId, halEndpointInfo.id, mHalEndpointInfo.id, serviceDescriptor);
} catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
@@ -263,8 +308,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
super.unregister_enforcePermission();
synchronized (mOpenSessionLock) {
// Iterate in reverse since cleanupSessionResources will remove the entry
- for (int i = mSessionInfoMap.size() - 1; i >= 0; i--) {
- int id = mSessionInfoMap.keyAt(i);
+ for (int i = mSessionMap.size() - 1; i >= 0; i--) {
+ int id = mSessionMap.keyAt(i);
halCloseEndpointSessionNoThrow(id, Reason.ENDPOINT_GONE);
cleanupSessionResources(id);
}
@@ -290,14 +335,14 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
public void openSessionRequestComplete(int sessionId) {
super.openSessionRequestComplete_enforcePermission();
synchronized (mOpenSessionLock) {
- SessionInfo info = mSessionInfoMap.get(sessionId);
+ Session info = mSessionMap.get(sessionId);
if (info == null) {
throw new IllegalArgumentException(
"openSessionRequestComplete for invalid session id=" + sessionId);
}
try {
mHubInterface.endpointSessionOpenComplete(sessionId);
- info.setSessionState(SessionInfo.SessionState.ACTIVE);
+ info.setSessionState(Session.SessionState.ACTIVE);
} catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
Log.e(TAG, "Exception while calling endpointSessionOpenComplete", e);
}
@@ -310,7 +355,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
super.sendMessage_enforcePermission();
synchronized (mOpenSessionLock) {
- SessionInfo info = mSessionInfoMap.get(sessionId);
+ Session info = mSessionMap.get(sessionId);
if (info == null) {
throw new IllegalArgumentException(
"sendMessage for invalid session id=" + sessionId);
@@ -393,9 +438,9 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
} else {
synchronized (mOpenSessionLock) {
// Iterate in reverse since cleanupSessionResources will remove the entry
- for (int i = mSessionInfoMap.size() - 1; i >= 0; i--) {
- int id = mSessionInfoMap.keyAt(i);
- HubEndpointInfo target = mSessionInfoMap.get(id).getRemoteEndpointInfo();
+ for (int i = mSessionMap.size() - 1; i >= 0; i--) {
+ int id = mSessionMap.keyAt(i);
+ HubEndpointInfo target = mSessionMap.get(id).getRemoteEndpointInfo();
if (!hasEndpointPermissions(target)) {
halCloseEndpointSessionNoThrow(id, Reason.PERMISSION_DENIED);
onCloseEndpointSession(id, Reason.PERMISSION_DENIED);
@@ -415,13 +460,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
sb.append("wakelock: ").append(mWakeLock);
}
synchronized (mOpenSessionLock) {
- if (mSessionInfoMap.size() != 0) {
+ if (mSessionMap.size() != 0) {
sb.append(System.lineSeparator());
sb.append(" sessions: ");
sb.append(System.lineSeparator());
}
- for (int i = 0; i < mSessionInfoMap.size(); i++) {
- int id = mSessionInfoMap.keyAt(i);
+ for (int i = 0; i < mSessionMap.size(); i++) {
+ int id = mSessionMap.keyAt(i);
int count = i + 1;
sb.append(
" "
@@ -429,7 +474,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
+ ". id="
+ id
+ ", remote:"
- + mSessionInfoMap.get(id).getRemoteEndpointInfo());
+ + mSessionMap.get(id).getRemoteEndpointInfo());
sb.append(System.lineSeparator());
}
}
@@ -485,23 +530,23 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
Log.w(TAG, "Unknown session ID in onEndpointSessionOpenComplete: id=" + sessionId);
return;
}
- mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE);
+ mSessionMap.get(sessionId).setSessionState(Session.SessionState.ACTIVE);
}
invokeCallback((consumer) -> consumer.onSessionOpenComplete(sessionId));
}
/* package */ void onMessageReceived(int sessionId, HubMessage message) {
- byte code = onMessageReceivedInternal(sessionId, message);
- if (code != ErrorCode.OK && message.isResponseRequired()) {
- sendMessageDeliveryStatus(sessionId, message.getMessageSequenceNumber(), code);
+ byte errorCode = onMessageReceivedInternal(sessionId, message);
+ if (errorCode != ErrorCode.OK && message.isResponseRequired()) {
+ sendMessageDeliveryStatus(sessionId, message.getMessageSequenceNumber(), errorCode);
}
}
/* package */ void onMessageDeliveryStatusReceived(
int sessionId, int sequenceNumber, byte errorCode) {
synchronized (mOpenSessionLock) {
- SessionInfo info = mSessionInfoMap.get(sessionId);
+ Session info = mSessionMap.get(sessionId);
if (info == null || !info.isActive()) {
Log.w(TAG, "Received delivery status for invalid session: id=" + sessionId);
return;
@@ -517,7 +562,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
/* package */ boolean hasSessionId(int sessionId) {
synchronized (mOpenSessionLock) {
- return mSessionInfoMap.contains(sessionId);
+ return mSessionMap.contains(sessionId);
}
}
@@ -531,8 +576,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
}
}
synchronized (mOpenSessionLock) {
- for (int i = mSessionInfoMap.size() - 1; i >= 0; i--) {
- int id = mSessionInfoMap.keyAt(i);
+ for (int i = mSessionMap.size() - 1; i >= 0; i--) {
+ int id = mSessionMap.keyAt(i);
onCloseEndpointSession(id, Reason.HUB_RESET);
}
}
@@ -555,7 +600,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
Log.e(TAG, "Existing session in onEndpointSessionOpenRequest: id=" + sessionId);
return Optional.of(Reason.UNSPECIFIED);
}
- mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true));
+ mSessionMap.put(sessionId, new Session(initiator, true));
}
boolean success =
@@ -567,7 +612,6 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
}
private byte onMessageReceivedInternal(int sessionId, HubMessage message) {
- HubEndpointInfo remote;
synchronized (mOpenSessionLock) {
if (!isSessionActive(sessionId)) {
Log.e(
@@ -578,29 +622,36 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
+ message);
return ErrorCode.PERMANENT_ERROR;
}
- remote = mSessionInfoMap.get(sessionId).getRemoteEndpointInfo();
- }
+ HubEndpointInfo remote = mSessionMap.get(sessionId).getRemoteEndpointInfo();
+ if (mSessionMap.get(sessionId).isInMessageHistory(message)) {
+ Log.e(TAG, "Dropping duplicate message: " + message);
+ return ErrorCode.TRANSIENT_ERROR;
+ }
- try {
- Binder.withCleanCallingIdentity(
- () -> {
- if (!notePermissions(remote)) {
- throw new RuntimeException(
- "Dropping message from "
- + remote
- + ". "
- + mPackageName
- + " doesn't have permission");
- }
- });
- } catch (RuntimeException e) {
- Log.e(TAG, e.getMessage());
- return ErrorCode.PERMISSION_DENIED;
- }
+ try {
+ Binder.withCleanCallingIdentity(
+ () -> {
+ if (!notePermissions(remote)) {
+ throw new RuntimeException(
+ "Dropping message from "
+ + remote
+ + ". "
+ + mPackageName
+ + " doesn't have permission");
+ }
+ });
+ } catch (RuntimeException e) {
+ Log.e(TAG, e.getMessage());
+ return ErrorCode.PERMISSION_DENIED;
+ }
- boolean success =
- invokeCallback((consumer) -> consumer.onMessageReceived(sessionId, message));
- return success ? ErrorCode.OK : ErrorCode.TRANSIENT_ERROR;
+ boolean success =
+ invokeCallback((consumer) -> consumer.onMessageReceived(sessionId, message));
+ if (success) {
+ mSessionMap.get(sessionId).addMessageToHistory(message);
+ }
+ return success ? ErrorCode.OK : ErrorCode.TRANSIENT_ERROR;
+ }
}
/**
@@ -634,7 +685,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
*/
private boolean cleanupSessionResources(int sessionId) {
synchronized (mOpenSessionLock) {
- SessionInfo info = mSessionInfoMap.get(sessionId);
+ Session info = mSessionMap.get(sessionId);
if (info != null) {
if (!info.isRemoteInitiated()) {
mEndpointManager.returnSessionId(sessionId);
@@ -644,7 +695,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
mTransactionManager.onMessageDeliveryResponse(
sequenceNumber, /* success= */ false);
});
- mSessionInfoMap.remove(sessionId);
+ mSessionMap.remove(sessionId);
}
return info != null;
}
@@ -656,7 +707,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
*/
private boolean isSessionActive(int sessionId) {
synchronized (mOpenSessionLock) {
- return hasSessionId(sessionId) && mSessionInfoMap.get(sessionId).isActive();
+ return hasSessionId(sessionId) && mSessionMap.get(sessionId).isActive();
}
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index debac9436bb3..f137de1b3e1d 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -25,8 +25,20 @@ import static android.media.MediaRouter2.SCANNING_STATE_SCANNING_FULL;
import static android.media.MediaRouter2.SCANNING_STATE_WHILE_INTERACTIVE;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
-
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_DESELECT_ROUTE;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_RELEASE_SESSION;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_SELECT_ROUTE;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_TRANSFER_TO_ROUTE;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_ROUTE_ID;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_SESSION_ID;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_MANAGER_RECORD_NOT_FOUND;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_PERMISSION_DENIED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED;
import android.Manifest;
import android.annotation.NonNull;
@@ -64,14 +76,12 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
-
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.media.flags.Flags;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
-
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -130,9 +140,14 @@ class MediaRouter2ServiceImpl {
private final ArrayMap<IBinder, RouterRecord> mAllRouterRecords = new ArrayMap<>();
@GuardedBy("mLock")
private final ArrayMap<IBinder, ManagerRecord> mAllManagerRecords = new ArrayMap<>();
+
@GuardedBy("mLock")
private int mCurrentActiveUserId = -1;
+ @GuardedBy("mLock")
+ private static final MediaRouterMetricLogger mMediaRouterMetricLogger =
+ new MediaRouterMetricLogger();
+
private final ActivityManager.OnUidImportanceListener mOnUidImportanceListener =
(uid, importance) -> {
synchronized (mLock) {
@@ -350,8 +365,8 @@ class MediaRouter2ServiceImpl {
}
}
- public void setDiscoveryRequestWithRouter2(@NonNull IMediaRouter2 router,
- @NonNull RouteDiscoveryPreference preference) {
+ public void setDiscoveryRequestWithRouter2(
+ @NonNull IMediaRouter2 router, @NonNull RouteDiscoveryPreference preference) {
Objects.requireNonNull(router, "router must not be null");
Objects.requireNonNull(preference, "preference must not be null");
@@ -409,8 +424,8 @@ class MediaRouter2ServiceImpl {
}
}
- public void setRouteVolumeWithRouter2(@NonNull IMediaRouter2 router,
- @NonNull MediaRoute2Info route, int volume) {
+ public void setRouteVolumeWithRouter2(
+ @NonNull IMediaRouter2 router, @NonNull MediaRoute2Info route, int volume) {
Objects.requireNonNull(router, "router must not be null");
Objects.requireNonNull(route, "route must not be null");
@@ -439,12 +454,7 @@ class MediaRouter2ServiceImpl {
try {
synchronized (mLock) {
requestCreateSessionWithRouter2Locked(
- requestId,
- managerRequestId,
- router,
- oldSession,
- route,
- sessionHints);
+ requestId, managerRequestId, router, oldSession, route, sessionHints);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -1326,6 +1336,9 @@ class MediaRouter2ServiceImpl {
final RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord == null) {
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return;
}
@@ -1344,15 +1357,22 @@ class MediaRouter2ServiceImpl {
if (managerRequestId != MediaRoute2ProviderService.REQUEST_ID_NONE) {
ManagerRecord manager = userHandler.findManagerWithId(toRequesterId(managerRequestId));
if (manager == null || manager.mLastSessionCreationRequest == null) {
- Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
- + "Ignoring unknown request.");
+ Slog.w(TAG, "requestCreateSessionWithRouter2Locked: Ignoring unknown request.");
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_MANAGER_RECORD_NOT_FOUND);
routerRecord.notifySessionCreationFailed(requestId);
return;
}
- if (!TextUtils.equals(manager.mLastSessionCreationRequest.mOldSession.getId(),
- oldSession.getId())) {
- Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
- + "Ignoring unmatched routing session.");
+ if (!TextUtils.equals(
+ manager.mLastSessionCreationRequest.mOldSession.getId(), oldSession.getId())) {
+ Slog.w(
+ TAG,
+ "requestCreateSessionWithRouter2Locked: "
+ + "Ignoring unmatched routing session.");
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_SESSION_ID);
routerRecord.notifySessionCreationFailed(requestId);
return;
}
@@ -1364,8 +1384,13 @@ class MediaRouter2ServiceImpl {
&& route.isSystemRoute()) {
route = manager.mLastSessionCreationRequest.mRoute;
} else {
- Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
- + "Ignoring unmatched route.");
+ Slog.w(
+ TAG,
+ "requestCreateSessionWithRouter2Locked: "
+ + "Ignoring unmatched route.");
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_ROUTE_ID);
routerRecord.notifySessionCreationFailed(requestId);
return;
}
@@ -1376,14 +1401,19 @@ class MediaRouter2ServiceImpl {
if (route.isSystemRoute()
&& !routerRecord.hasSystemRoutingPermission()
&& !TextUtils.equals(route.getId(), defaultRouteId)) {
- Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to"
- + route);
+ Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to" + route);
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_PERMISSION_DENIED);
routerRecord.notifySessionCreationFailed(requestId);
return;
}
}
long uniqueRequestId = toUniqueRequestId(routerRecord.mRouterId, requestId);
+ mMediaRouterMetricLogger.addRequestInfo(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION);
userHandler.sendMessage(
obtainMessage(
UserHandler::requestCreateSessionWithRouter2OnHandler,
@@ -1403,6 +1433,9 @@ class MediaRouter2ServiceImpl {
final RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord == null) {
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_SELECT_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return;
}
@@ -1411,6 +1444,9 @@ class MediaRouter2ServiceImpl {
TextUtils.formatSimple(
"selectRouteWithRouter2 | router: %s(id: %d), route: %s",
routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
+ mMediaRouterMetricLogger.logOperationTriggered(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_SELECT_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::selectRouteOnHandler,
@@ -1425,6 +1461,9 @@ class MediaRouter2ServiceImpl {
final RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord == null) {
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_DESELECT_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return;
}
@@ -1433,6 +1472,9 @@ class MediaRouter2ServiceImpl {
TextUtils.formatSimple(
"deselectRouteWithRouter2 | router: %s(id: %d), route: %s",
routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
+ mMediaRouterMetricLogger.logOperationTriggered(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_DESELECT_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::deselectRouteOnHandler,
@@ -1450,6 +1492,9 @@ class MediaRouter2ServiceImpl {
final RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord == null) {
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_TRANSFER_TO_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return;
}
@@ -1458,6 +1503,9 @@ class MediaRouter2ServiceImpl {
TextUtils.formatSimple(
"transferToRouteWithRouter2 | router: %s(id: %d), route: %s",
routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
+ mMediaRouterMetricLogger.logOperationTriggered(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_TRANSFER_TO_ROUTE,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
UserHandler userHandler = routerRecord.mUserRecord.mHandler;
String defaultRouteId = userHandler.getSystemProvider().getDefaultRoute().getId();
@@ -1516,6 +1564,9 @@ class MediaRouter2ServiceImpl {
final RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord == null) {
+ mMediaRouterMetricLogger.logOperationFailure(
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_RELEASE_SESSION,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return;
}
@@ -1794,6 +1845,9 @@ class MediaRouter2ServiceImpl {
.findRouterWithSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
+ mMediaRouterMetricLogger.addRequestInfo(
+ uniqueRequestId, MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_SELECT_ROUTE);
+
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::selectRouteOnHandler,
managerRecord.mUserRecord.mHandler,
@@ -1820,6 +1874,10 @@ class MediaRouter2ServiceImpl {
.findRouterWithSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
+ mMediaRouterMetricLogger.addRequestInfo(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_DESELECT_ROUTE);
+
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::deselectRouteOnHandler,
managerRecord.mUserRecord.mHandler,
@@ -1851,6 +1909,10 @@ class MediaRouter2ServiceImpl {
.findRouterWithSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
+ mMediaRouterMetricLogger.addRequestInfo(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_TRANSFER_TO_ROUTE);
+
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(
UserHandler::transferToRouteOnHandler,
@@ -2792,7 +2854,8 @@ class MediaRouter2ServiceImpl {
if (!addedRoutes.isEmpty()) {
// If routes were added, newInfo cannot be null.
- Slog.i(TAG,
+ Slog.i(
+ TAG,
toLoggingMessage(
/* source= */ "addProviderRoutes",
newInfo.getUniqueId(),
@@ -2954,7 +3017,7 @@ class MediaRouter2ServiceImpl {
private void selectRouteOnHandler(long uniqueRequestId, @Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
- "selecting")) {
+ "selecting", uniqueRequestId)) {
return;
}
@@ -2963,8 +3026,12 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
- provider.selectRoute(uniqueRequestId, getOriginalId(uniqueSessionId),
- route.getOriginalId());
+ provider.selectRoute(
+ uniqueRequestId, getOriginalId(uniqueSessionId), route.getOriginalId());
+
+ // Log the success result.
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId, MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS);
}
// routerRecord can be null if the session is system's or RCN.
@@ -2972,7 +3039,7 @@ class MediaRouter2ServiceImpl {
@Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
- "deselecting")) {
+ "deselecting", uniqueRequestId)) {
return;
}
@@ -2982,8 +3049,12 @@ class MediaRouter2ServiceImpl {
return;
}
- provider.deselectRoute(uniqueRequestId, getOriginalId(uniqueSessionId),
- route.getOriginalId());
+ provider.deselectRoute(
+ uniqueRequestId, getOriginalId(uniqueSessionId), route.getOriginalId());
+
+ // Log the success result.
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId, MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS);
}
// routerRecord can be null if the session is system's or RCN.
@@ -2996,7 +3067,7 @@ class MediaRouter2ServiceImpl {
@NonNull MediaRoute2Info route,
@RoutingSessionInfo.TransferReason int transferReason) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
- "transferring to")) {
+ "transferring to", uniqueRequestId)) {
return;
}
@@ -3016,18 +3087,25 @@ class MediaRouter2ServiceImpl {
getOriginalId(uniqueSessionId),
route.getOriginalId(),
transferReason);
+
+ // Log the success result.
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId, MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS);
}
// routerRecord is null if and only if the session is created without the request, which
// includes the system's session and RCN cases.
private boolean checkArgumentsForSessionControl(@Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route,
- @NonNull String description) {
+ @NonNull String description, long uniqueRequestId) {
final String providerId = route.getProviderId();
final MediaRoute2Provider provider = findProvider(providerId);
if (provider == null) {
Slog.w(TAG, "Ignoring " + description + " route since no provider found for "
+ "given route=" + route);
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND);
return false;
}
@@ -3050,6 +3128,9 @@ class MediaRouter2ServiceImpl {
+ getPackageNameFromNullableRecord(matchingRecord)
+ " route="
+ route);
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTER_RECORD_NOT_FOUND);
return false;
}
@@ -3057,6 +3138,9 @@ class MediaRouter2ServiceImpl {
if (sessionId == null) {
Slog.w(TAG, "Failed to get original session id from unique session id. "
+ "uniqueSessionId=" + uniqueSessionId);
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_SESSION_ID);
return false;
}
@@ -3168,6 +3252,10 @@ class MediaRouter2ServiceImpl {
}
matchingRequest.mRouterRecord.notifySessionCreated(
toOriginalRequestId(uniqueRequestId), sessionInfo);
+
+ // Log the success result.
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId, MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS);
}
/**
@@ -3255,10 +3343,14 @@ class MediaRouter2ServiceImpl {
// Currently, only manager records can get notified of failures.
// TODO(b/282936553): Notify regular routers of request failures.
+
+ // Log the request result.
+ mMediaRouterMetricLogger.logRequestResult(
+ uniqueRequestId, MediaRouterMetricLogger.convertResultFromReason(reason));
}
- private boolean handleSessionCreationRequestFailed(@NonNull MediaRoute2Provider provider,
- long uniqueRequestId, int reason) {
+ private boolean handleSessionCreationRequestFailed(
+ @NonNull MediaRoute2Provider provider, long uniqueRequestId, int reason) {
// Check whether the failure is about creating a session
SessionCreationRequest matchingRequest = null;
for (SessionCreationRequest request : mSessionCreationRequests) {
@@ -3385,8 +3477,8 @@ class MediaRouter2ServiceImpl {
}
}
- private void notifySessionCreatedToManagers(long managerRequestId,
- @NonNull RoutingSessionInfo session) {
+ private void notifySessionCreatedToManagers(
+ long managerRequestId, @NonNull RoutingSessionInfo session) {
int requesterId = toRequesterId(managerRequestId);
int originalRequestId = toOriginalRequestId(managerRequestId);
diff --git a/services/core/java/com/android/server/media/MediaRouterMetricLogger.java b/services/core/java/com/android/server/media/MediaRouterMetricLogger.java
new file mode 100644
index 000000000000..56d2a1b22254
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRouterMetricLogger.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_FAILED_TO_REROUTE_SYSTEM_MEDIA;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_NETWORK_ERROR;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_REJECTED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTE_NOT_AVAILABLE;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNIMPLEMENTED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNKNOWN_ERROR;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED;
+
+import android.annotation.NonNull;
+import android.media.MediaRoute2ProviderService;
+import android.util.Log;
+import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Logs metrics for MediaRouter2.
+ *
+ * @hide
+ */
+final class MediaRouterMetricLogger {
+ private static final String TAG = "MediaRouterMetricLogger";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int REQUEST_INFO_CACHE_CAPACITY = 100;
+
+ /** LRU cache to store request info. */
+ private final RequestInfoCache mRequestInfoCache;
+
+ /** Constructor for {@link MediaRouterMetricLogger}. */
+ public MediaRouterMetricLogger() {
+ mRequestInfoCache = new RequestInfoCache(REQUEST_INFO_CACHE_CAPACITY);
+ }
+
+ /**
+ * Adds a new request info to the cache.
+ *
+ * @param uniqueRequestId The unique request id.
+ * @param eventType The event type.
+ */
+ public void addRequestInfo(long uniqueRequestId, int eventType) {
+ RequestInfo requestInfo = new RequestInfo(uniqueRequestId, eventType);
+ mRequestInfoCache.put(requestInfo.mUniqueRequestId, requestInfo);
+ }
+
+ /**
+ * Removes a request info from the cache.
+ *
+ * @param uniqueRequestId The unique request id.
+ */
+ public void removeRequestInfo(long uniqueRequestId) {
+ mRequestInfoCache.remove(uniqueRequestId);
+ }
+
+ /**
+ * Logs an operation failure.
+ *
+ * @param eventType The event type.
+ * @param result The result of the operation.
+ */
+ public void logOperationFailure(int eventType, int result) {
+ logMediaRouterEvent(eventType, result);
+ }
+
+ /**
+ * Logs an operation triggered.
+ *
+ * @param eventType The event type.
+ */
+ public void logOperationTriggered(int eventType, int result) {
+ logMediaRouterEvent(eventType, result);
+ }
+
+ /**
+ * Logs the result of a request.
+ *
+ * @param uniqueRequestId The unique request id.
+ * @param result The result of the request.
+ */
+ public void logRequestResult(long uniqueRequestId, int result) {
+ RequestInfo requestInfo = mRequestInfoCache.get(uniqueRequestId);
+ if (requestInfo == null) {
+ Slog.w(
+ TAG,
+ "logRequestResult: No RequestInfo found for uniqueRequestId="
+ + uniqueRequestId);
+ return;
+ }
+
+ int eventType = requestInfo.mEventType;
+ logMediaRouterEvent(eventType, result);
+
+ removeRequestInfo(uniqueRequestId);
+ }
+
+ /**
+ * Converts a reason code from {@link MediaRoute2ProviderService} to a result code for logging.
+ *
+ * @param reason The reason code from {@link MediaRoute2ProviderService}.
+ * @return The result code for logging.
+ */
+ public static int convertResultFromReason(int reason) {
+ switch (reason) {
+ case MediaRoute2ProviderService.REASON_UNKNOWN_ERROR:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNKNOWN_ERROR;
+ case MediaRoute2ProviderService.REASON_REJECTED:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_REJECTED;
+ case MediaRoute2ProviderService.REASON_NETWORK_ERROR:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_NETWORK_ERROR;
+ case MediaRoute2ProviderService.REASON_ROUTE_NOT_AVAILABLE:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTE_NOT_AVAILABLE;
+ case MediaRoute2ProviderService.REASON_INVALID_COMMAND:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND;
+ case MediaRoute2ProviderService.REASON_UNIMPLEMENTED:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNIMPLEMENTED;
+ case MediaRoute2ProviderService.REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_FAILED_TO_REROUTE_SYSTEM_MEDIA;
+ default:
+ return MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED;
+ }
+ }
+
+ /**
+ * Gets the size of the request info cache.
+ *
+ * @return The size of the request info cache.
+ */
+ @VisibleForTesting
+ public int getRequestCacheSize() {
+ return mRequestInfoCache.size();
+ }
+
+ private void logMediaRouterEvent(int eventType, int result) {
+ MediaRouterStatsLog.write(
+ MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED, eventType, result);
+
+ if (DEBUG) {
+ Slog.d(TAG, "logMediaRouterEvent: " + eventType + " " + result);
+ }
+ }
+
+ /** A cache for storing request info that evicts entries when it reaches its capacity. */
+ class RequestInfoCache extends LinkedHashMap<Long, RequestInfo> {
+
+ public final int capacity;
+
+ /**
+ * Constructor for {@link RequestInfoCache}.
+ *
+ * @param capacity The maximum capacity of the cache.
+ */
+ public RequestInfoCache(int capacity) {
+ super(capacity, 1.0f, true);
+ this.capacity = capacity;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<Long, RequestInfo> eldest) {
+ boolean shouldRemove = size() > capacity;
+ if (shouldRemove) {
+ Slog.d(TAG, "Evicted request info: " + eldest.getValue());
+ logOperationTriggered(
+ eldest.getValue().mEventType,
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
+ }
+ return shouldRemove;
+ }
+ }
+
+ /** Class to store request info. */
+ static class RequestInfo {
+ public final long mUniqueRequestId;
+ public final int mEventType;
+
+ /**
+ * Constructor for {@link RequestInfo}.
+ *
+ * @param uniqueRequestId The unique request id.
+ * @param eventType The event type.
+ */
+ RequestInfo(long uniqueRequestId, int eventType) {
+ mUniqueRequestId = uniqueRequestId;
+ mEventType = eventType;
+ }
+
+ /**
+ * Dumps the request info.
+ *
+ * @param pw The print writer.
+ * @param prefix The prefix for the output.
+ */
+ public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
+ pw.println(prefix + "RequestInfo");
+ String indent = prefix + " ";
+ pw.println(indent + "mUniqueRequestId=" + mUniqueRequestId);
+ pw.println(indent + "mEventType=" + mEventType);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index 91a2843ccaf7..9e38435ff7f1 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -48,7 +48,6 @@ import android.media.quality.IMediaQualityManager;
import android.media.quality.IPictureProfileCallback;
import android.media.quality.ISoundProfileCallback;
import android.media.quality.MediaQualityContract.BaseParameters;
-import android.media.quality.MediaQualityManager;
import android.media.quality.ParameterCapability;
import android.media.quality.PictureProfile;
import android.media.quality.PictureProfileHandle;
@@ -187,7 +186,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public PictureProfile createPictureProfile(PictureProfile pp, UserHandle user) {
+ public PictureProfile createPictureProfile(PictureProfile pp, int userId) {
if ((pp.getPackageName() != null && !pp.getPackageName().isEmpty()
&& !incomingPackageEqualsCallingUidPackage(pp.getPackageName()))
&& !hasGlobalPictureQualityServicePermission()) {
@@ -221,7 +220,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public void updatePictureProfile(String id, PictureProfile pp, UserHandle user) {
+ public void updatePictureProfile(String id, PictureProfile pp, int userId) {
Long dbId = mPictureProfileTempIdMap.getKey(id);
if (!hasPermissionToUpdatePictureProfile(dbId, pp)) {
mMqManagerNotifier.notifyOnPictureProfileError(id,
@@ -249,7 +248,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public void removePictureProfile(String id, UserHandle user) {
+ public void removePictureProfile(String id, int userId) {
synchronized (mPictureProfileLock) {
Long dbId = mPictureProfileTempIdMap.getKey(id);
@@ -290,10 +289,8 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public PictureProfile getPictureProfile(int type, String name, Bundle options,
- UserHandle user) {
- boolean includeParams =
- options.getBoolean(MediaQualityManager.OPTION_INCLUDE_PARAMETERS, false);
+ public PictureProfile getPictureProfile(int type, String name, boolean includeParams,
+ int userId) {
String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
+ BaseParameters.PARAMETER_NAME + " = ? AND "
+ BaseParameters.PARAMETER_PACKAGE + " = ?";
@@ -327,7 +324,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
public List<PictureProfile> getPictureProfilesByPackage(
- String packageName, Bundle options, UserHandle user) {
+ String packageName, boolean includeParams, int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -335,8 +332,6 @@ public class MediaQualityService extends SystemService {
}
synchronized (mPictureProfileLock) {
- boolean includeParams =
- options.getBoolean(MediaQualityManager.OPTION_INCLUDE_PARAMETERS, false);
String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
String[] selectionArguments = {packageName};
return mMqDatabaseUtils.getPictureProfilesBasedOnConditions(MediaQualityUtils
@@ -347,17 +342,17 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public List<PictureProfile> getAvailablePictureProfiles(Bundle options, UserHandle user) {
+ public List<PictureProfile> getAvailablePictureProfiles(boolean includeParams, int userId) {
String packageName = getPackageOfCallingUid();
if (packageName != null) {
- return getPictureProfilesByPackage(packageName, options, user);
+ return getPictureProfilesByPackage(packageName, includeParams, userId);
}
return new ArrayList<>();
}
@GuardedBy("mPictureProfileLock")
@Override
- public boolean setDefaultPictureProfile(String profileId, UserHandle user) {
+ public boolean setDefaultPictureProfile(String profileId, int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(profileId,
PictureProfile.ERROR_NO_PERMISSION,
@@ -387,7 +382,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public List<String> getPictureProfilePackageNames(UserHandle user) {
+ public List<String> getPictureProfilePackageNames(int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -406,7 +401,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public List<PictureProfileHandle> getPictureProfileHandle(String[] ids, UserHandle user) {
+ public List<PictureProfileHandle> getPictureProfileHandle(String[] ids, int userId) {
List<PictureProfileHandle> toReturn = new ArrayList<>();
synchronized (mPictureProfileLock) {
for (String id : ids) {
@@ -423,13 +418,13 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public List<SoundProfileHandle> getSoundProfileHandle(String[] ids, UserHandle user) {
+ public List<SoundProfileHandle> getSoundProfileHandle(String[] ids, int userId) {
List<SoundProfileHandle> toReturn = new ArrayList<>();
synchronized (mSoundProfileLock) {
for (String id : ids) {
Long key = mSoundProfileTempIdMap.getKey(id);
if (key != null) {
- toReturn.add(new SoundProfileHandle(key));
+ toReturn.add(MediaQualityUtils.SOUND_PROFILE_HANDLE_NONE);
} else {
toReturn.add(null);
}
@@ -440,7 +435,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public SoundProfile createSoundProfile(SoundProfile sp, UserHandle user) {
+ public SoundProfile createSoundProfile(SoundProfile sp, int userId) {
if ((sp.getPackageName() != null && !sp.getPackageName().isEmpty()
&& !incomingPackageEqualsCallingUidPackage(sp.getPackageName()))
&& !hasGlobalPictureQualityServicePermission()) {
@@ -473,7 +468,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public void updateSoundProfile(String id, SoundProfile sp, UserHandle user) {
+ public void updateSoundProfile(String id, SoundProfile sp, int userId) {
Long dbId = mSoundProfileTempIdMap.getKey(id);
if (!hasPermissionToUpdateSoundProfile(dbId, sp)) {
mMqManagerNotifier.notifyOnSoundProfileError(id, SoundProfile.ERROR_NO_PERMISSION,
@@ -502,7 +497,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public void removeSoundProfile(String id, UserHandle user) {
+ public void removeSoundProfile(String id, int userId) {
synchronized (mSoundProfileLock) {
Long dbId = mSoundProfileTempIdMap.getKey(id);
SoundProfile toDelete = mMqDatabaseUtils.getSoundProfile(dbId);
@@ -542,10 +537,8 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public SoundProfile getSoundProfile(int type, String name, Bundle options,
- UserHandle user) {
- boolean includeParams =
- options.getBoolean(MediaQualityManager.OPTION_INCLUDE_PARAMETERS, false);
+ public SoundProfile getSoundProfile(int type, String name, boolean includeParams,
+ int userId) {
String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
+ BaseParameters.PARAMETER_NAME + " = ? AND "
+ BaseParameters.PARAMETER_PACKAGE + " = ?";
@@ -579,15 +572,13 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
public List<SoundProfile> getSoundProfilesByPackage(
- String packageName, Bundle options, UserHandle user) {
+ String packageName, boolean includeParams, int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(null, SoundProfile.ERROR_NO_PERMISSION,
Binder.getCallingUid(), Binder.getCallingPid());
}
synchronized (mSoundProfileLock) {
- boolean includeParams =
- options.getBoolean(MediaQualityManager.OPTION_INCLUDE_PARAMETERS, false);
String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
String[] selectionArguments = {packageName};
return mMqDatabaseUtils.getSoundProfilesBasedOnConditions(MediaQualityUtils
@@ -598,17 +589,17 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public List<SoundProfile> getAvailableSoundProfiles(Bundle options, UserHandle user) {
+ public List<SoundProfile> getAvailableSoundProfiles(boolean includeParams, int userId) {
String packageName = getPackageOfCallingUid();
if (packageName != null) {
- return getSoundProfilesByPackage(packageName, options, user);
+ return getSoundProfilesByPackage(packageName, includeParams, userId);
}
return new ArrayList<>();
}
@GuardedBy("mSoundProfileLock")
@Override
- public boolean setDefaultSoundProfile(String profileId, UserHandle user) {
+ public boolean setDefaultSoundProfile(String profileId, int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(profileId,
SoundProfile.ERROR_NO_PERMISSION,
@@ -638,7 +629,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public List<String> getSoundProfilePackageNames(UserHandle user) {
+ public List<String> getSoundProfilePackageNames(int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(null, SoundProfile.ERROR_NO_PERMISSION,
Binder.getCallingUid(), Binder.getCallingPid());
@@ -737,7 +728,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mAmbientBacklightLock")
@Override
public void setAmbientBacklightSettings(
- AmbientBacklightSettings settings, UserHandle user) {
+ AmbientBacklightSettings settings, int userId) {
if (DEBUG) {
Slogf.d(TAG, "setAmbientBacklightSettings " + settings);
}
@@ -775,7 +766,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mAmbientBacklightLock")
@Override
- public void setAmbientBacklightEnabled(boolean enabled, UserHandle user) {
+ public void setAmbientBacklightEnabled(boolean enabled, int userId) {
if (DEBUG) {
Slogf.d(TAG, "setAmbientBacklightEnabled " + enabled);
}
@@ -795,7 +786,7 @@ public class MediaQualityService extends SystemService {
@Override
public List<ParameterCapability> getParameterCapabilities(
- List<String> names, UserHandle user) {
+ List<String> names, int userId) {
byte[] byteArray = MediaQualityUtils.convertParameterToByteArray(names);
ParamCapability[] caps = new ParamCapability[byteArray.length];
try {
@@ -828,7 +819,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public List<String> getPictureProfileAllowList(UserHandle user) {
+ public List<String> getPictureProfileAllowList(int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -844,7 +835,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public void setPictureProfileAllowList(List<String> packages, UserHandle user) {
+ public void setPictureProfileAllowList(List<String> packages, int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -857,7 +848,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public List<String> getSoundProfileAllowList(UserHandle user) {
+ public List<String> getSoundProfileAllowList(int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(null, SoundProfile.ERROR_NO_PERMISSION,
Binder.getCallingUid(), Binder.getCallingPid());
@@ -872,7 +863,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public void setSoundProfileAllowList(List<String> packages, UserHandle user) {
+ public void setSoundProfileAllowList(List<String> packages, int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(null, SoundProfile.ERROR_NO_PERMISSION,
Binder.getCallingUid(), Binder.getCallingPid());
@@ -883,13 +874,13 @@ public class MediaQualityService extends SystemService {
}
@Override
- public boolean isSupported(UserHandle user) {
+ public boolean isSupported(int userId) {
return false;
}
@GuardedBy("mPictureProfileLock")
@Override
- public void setAutoPictureQualityEnabled(boolean enabled, UserHandle user) {
+ public void setAutoPictureQualityEnabled(boolean enabled, int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -910,7 +901,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public boolean isAutoPictureQualityEnabled(UserHandle user) {
+ public boolean isAutoPictureQualityEnabled(int userId) {
synchronized (mPictureProfileLock) {
try {
if (mMediaQuality != null) {
@@ -927,7 +918,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public void setSuperResolutionEnabled(boolean enabled, UserHandle user) {
+ public void setSuperResolutionEnabled(boolean enabled, int userId) {
if (!hasGlobalPictureQualityServicePermission()) {
mMqManagerNotifier.notifyOnPictureProfileError(null,
PictureProfile.ERROR_NO_PERMISSION,
@@ -948,7 +939,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mPictureProfileLock")
@Override
- public boolean isSuperResolutionEnabled(UserHandle user) {
+ public boolean isSuperResolutionEnabled(int userId) {
synchronized (mPictureProfileLock) {
try {
if (mMediaQuality != null) {
@@ -965,7 +956,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public void setAutoSoundQualityEnabled(boolean enabled, UserHandle user) {
+ public void setAutoSoundQualityEnabled(boolean enabled, int userId) {
if (!hasGlobalSoundQualityServicePermission()) {
mMqManagerNotifier.notifyOnSoundProfileError(null, SoundProfile.ERROR_NO_PERMISSION,
Binder.getCallingUid(), Binder.getCallingPid());
@@ -986,7 +977,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mSoundProfileLock")
@Override
- public boolean isAutoSoundQualityEnabled(UserHandle user) {
+ public boolean isAutoSoundQualityEnabled(int userId) {
synchronized (mSoundProfileLock) {
try {
if (mMediaQuality != null) {
@@ -1003,7 +994,7 @@ public class MediaQualityService extends SystemService {
@GuardedBy("mAmbientBacklightLock")
@Override
- public boolean isAmbientBacklightEnabled(UserHandle user) {
+ public boolean isAmbientBacklightEnabled(int userId) {
return false;
}
}
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
index 88d3f1ff7c52..303c96750098 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
@@ -60,6 +60,11 @@ public final class MediaQualityUtils {
private static final String TAG = "MediaQualityUtils";
public static final String SETTINGS = "settings";
+ public static final SoundProfileHandle SOUND_PROFILE_HANDLE_NONE = new SoundProfileHandle();
+ static {
+ SOUND_PROFILE_HANDLE_NONE.id = -10000;
+ }
+
/**
* Convert PictureParameter List to PersistableBundle.
*/
@@ -1022,7 +1027,7 @@ public final class MediaQualityUtils {
getInputId(cursor),
getPackageName(cursor),
jsonToPersistableBundle(getSettingsString(cursor)),
- SoundProfileHandle.NONE
+ SOUND_PROFILE_HANDLE_NONE
);
}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 6e5308e56aa8..3f4df1dcf4e9 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -1002,8 +1002,7 @@ public class GroupHelper {
private FullyQualifiedGroupKey getSectionGroupKeyWithFallback(final NotificationRecord record) {
final NotificationSectioner sectioner = getSection(record);
if (sectioner != null) {
- return new FullyQualifiedGroupKey(record.getUserId(), record.getSbn().getPackageName(),
- sectioner);
+ return FullyQualifiedGroupKey.forRecord(record, sectioner);
} else {
return getPreviousValidSectionKey(record);
}
@@ -1105,6 +1104,49 @@ public class GroupHelper {
}
}
+ /**
+ * Called when a group summary is posted. If there are any ungrouped notifications that are
+ * in that group, remove them as they are no longer candidates for autogrouping.
+ *
+ * @param summaryRecord the NotificationRecord for the newly posted group summary
+ * @param notificationList the full notification list from NotificationManagerService
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+ protected void onGroupSummaryAdded(final NotificationRecord summaryRecord,
+ final List<NotificationRecord> notificationList) {
+ String groupKey = summaryRecord.getSbn().getGroup();
+ synchronized (mAggregatedNotifications) {
+ final NotificationSectioner sectioner = getSection(summaryRecord);
+ if (sectioner == null) {
+ Slog.w(TAG, "onGroupSummaryAdded " + summaryRecord + ": no valid section found");
+ return;
+ }
+
+ FullyQualifiedGroupKey aggregateGroupKey = FullyQualifiedGroupKey.forRecord(
+ summaryRecord, sectioner);
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(aggregateGroupKey,
+ new ArrayMap<>());
+ if (ungrouped.isEmpty()) {
+ // don't bother looking through the notification list if there are no pending
+ // ungrouped notifications in this section (likely to be the most common case)
+ return;
+ }
+
+ // Look through full notification list for any notifications belonging to this group;
+ // remove from ungrouped map if needed, as the presence of the summary means they will
+ // now be grouped
+ for (NotificationRecord r : notificationList) {
+ if (!r.getNotification().isGroupSummary()
+ && groupKey.equals(r.getSbn().getGroup())
+ && ungrouped.containsKey(r.getKey())) {
+ ungrouped.remove(r.getKey());
+ }
+ }
+ mUngroupedAbuseNotifications.put(aggregateGroupKey, ungrouped);
+ }
+ }
+
private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
FullyQualifiedGroupKey newGroup) { }
@@ -1496,8 +1538,8 @@ public class GroupHelper {
private boolean isNotificationAggregatedInSection(NotificationRecord record,
NotificationSectioner sectioner) {
- final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
- record.getUserId(), record.getSbn().getPackageName(), sectioner);
+ final FullyQualifiedGroupKey fullAggregateGroupKey = FullyQualifiedGroupKey.forRecord(
+ record, sectioner);
return record.getGroupKey().equals(fullAggregateGroupKey.toString());
}
@@ -1895,6 +1937,12 @@ public class GroupHelper {
this(userId, pkg, AGGREGATE_GROUP_KEY + (sectioner != null ? sectioner.mName : ""));
}
+ static FullyQualifiedGroupKey forRecord(NotificationRecord record,
+ @Nullable NotificationSectioner sectioner) {
+ return new FullyQualifiedGroupKey(record.getUserId(), record.getSbn().getPackageName(),
+ sectioner);
+ }
+
@Override
public String toString() {
return userId + "|" + pkg + "|" + "g:" + groupName;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0f1d28db8d82..bfe0d32f4cb6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -10196,6 +10196,12 @@ public class NotificationManagerService extends SystemService {
}
if (isSummary) {
mSummaryByGroupKey.put(group, r);
+
+ if (notificationForceGrouping()) {
+ // If any formerly-ungrouped notifications will be grouped by this summary, update
+ // accordingly.
+ mGroupHelper.onGroupSummaryAdded(r, mNotificationList);
+ }
}
FlagChecker childrenFlagChecker = (flags) -> {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 635ef069741b..af788ea6ccdb 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_INSTA
import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_UPDATED_BY_DO;
import static android.content.pm.DataLoaderType.INCREMENTAL;
import static android.content.pm.DataLoaderType.STREAMING;
+import static android.content.pm.Flags.cloudCompilationVerification;
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
import static android.content.pm.PackageInstaller.UNARCHIVAL_STATUS_UNSET;
@@ -3687,6 +3688,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
CollectionUtils.addAll(stagedSplitTypes, apk.getSplitTypes());
}
+ if (cloudCompilationVerification()) {
+ verifySdmSignatures(artManagedFilePaths, mSigningDetails);
+ }
+
if (removeSplitList.size() > 0) {
if (pkgInfo == null) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
@@ -4028,6 +4033,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
File targetArtManagedFile = new File(
ArtManagedInstallFileHelper.getTargetPathForApk(path, targetFile.getPath()));
stageFileLocked(artManagedFile, targetArtManagedFile);
+ if (!artManagedFile.equals(targetArtManagedFile)) {
+ // The file has been renamed. Update the list to reflect the change.
+ for (int i = 0; i < artManagedFilePaths.size(); ++i) {
+ if (artManagedFilePaths.get(i).equals(path)) {
+ artManagedFilePaths.set(i, targetArtManagedFile.getAbsolutePath());
+ }
+ }
+ }
}
}
@@ -4309,6 +4322,37 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
/**
+ * Verifies the signatures of SDM files.
+ *
+ * SDM is a file format that contains the cloud compilation artifacts. As a requirement, the SDM
+ * file should be signed with the same key as the APK.
+ *
+ * TODO(b/377474232): Move this logic to ART Service.
+ */
+ private static void verifySdmSignatures(List<String> artManagedFilePaths,
+ SigningDetails expectedSigningDetails) throws PackageManagerException {
+ ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+ for (String path : artManagedFilePaths) {
+ if (!path.endsWith(".sdm")) {
+ continue;
+ }
+ // SDM is a format introduced in Android 16, so we don't need to support older
+ // signature schemes.
+ int minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3;
+ ParseResult<SigningDetails> verified =
+ ApkSignatureVerifier.verify(input, path, minSignatureScheme);
+ if (verified.isError()) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_INVALID_APK, "Failed to verify SDM signatures");
+ }
+ if (!expectedSigningDetails.signaturesMatchExactly(verified.getResult())) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_INVALID_APK, "SDM signatures are inconsistent with APK");
+ }
+ }
+ }
+
+ /**
* @return the uid of the owner this session
*/
public int getInstallerUid() {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index d3513053caf3..66e9e772e063 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1792,7 +1792,7 @@ public class ShortcutService extends IShortcutService.Stub {
void injectPostToHandlerDebounced(@NonNull final Object token, @NonNull final Runnable r) {
Objects.requireNonNull(token);
Objects.requireNonNull(r);
- synchronized (mServiceLock) {
+ synchronized (mHandler) {
mHandler.removeCallbacksAndMessages(token);
mHandler.postDelayed(r, token, CALLBACK_DELAY);
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 6ab30595e46b..098f113dc11a 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -897,7 +897,7 @@ final class DefaultPermissionGrantPolicy {
SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId);
grantPermissionsToSystemPackage(pm, voiceSearchPackage,
userId, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS,
- COARSE_BACKGROUND_LOCATION_PERMISSIONS);
+ COARSE_BACKGROUND_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
revokeRuntimePermissions(pm, voiceSearchPackage,
FINE_LOCATION_PERMISSIONS, false, userId);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 22f20028eb9c..46dc75817a36 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3801,7 +3801,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true;
}
}
- // fall through
+ break;
case KeyEvent.KEYCODE_ESCAPE:
if (firstDown && event.isMetaPressed()) {
notifyKeyGestureCompleted(event,
diff --git a/services/core/java/com/android/server/power/ScreenUndimDetector.java b/services/core/java/com/android/server/power/ScreenUndimDetector.java
index c4929c210e2c..b376417061db 100644
--- a/services/core/java/com/android/server/power/ScreenUndimDetector.java
+++ b/services/core/java/com/android/server/power/ScreenUndimDetector.java
@@ -30,11 +30,11 @@ import android.provider.DeviceConfig;
import android.util.Slog;
import android.view.Display;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
/**
* Detects when user manually undims the screen (x times) and acquires a wakelock to keep the screen
@@ -48,7 +48,6 @@ public class ScreenUndimDetector {
/** DeviceConfig flag: is keep screen on feature enabled. */
static final String KEY_KEEP_SCREEN_ON_ENABLED = "keep_screen_on_enabled";
- private static final boolean DEFAULT_KEEP_SCREEN_ON_ENABLED = true;
private static final int OUTCOME_POWER_BUTTON =
FrameworkStatsLog.TIMEOUT_AUTO_EXTENDED_REPORTED__OUTCOME__POWER_BUTTON;
private static final int OUTCOME_TIMEOUT =
@@ -58,15 +57,11 @@ public class ScreenUndimDetector {
/** DeviceConfig flag: how long should we keep the screen on. */
@VisibleForTesting
static final String KEY_KEEP_SCREEN_ON_FOR_MILLIS = "keep_screen_on_for_millis";
- @VisibleForTesting
- static final long DEFAULT_KEEP_SCREEN_ON_FOR_MILLIS = TimeUnit.MINUTES.toMillis(10);
private long mKeepScreenOnForMillis;
/** DeviceConfig flag: how many user undims required to trigger keeping the screen on. */
@VisibleForTesting
static final String KEY_UNDIMS_REQUIRED = "undims_required";
- @VisibleForTesting
- static final int DEFAULT_UNDIMS_REQUIRED = 2;
private int mUndimsRequired;
/**
@@ -76,8 +71,6 @@ public class ScreenUndimDetector {
@VisibleForTesting
static final String KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS =
"max_duration_between_undims_millis";
- @VisibleForTesting
- static final long DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS = TimeUnit.MINUTES.toMillis(5);
private long mMaxDurationBetweenUndimsMillis;
@VisibleForTesting
@@ -92,6 +85,7 @@ public class ScreenUndimDetector {
private long mUndimOccurredTime = -1;
private long mInteractionAfterUndimTime = -1;
private InternalClock mClock;
+ private Context mContext;
public ScreenUndimDetector() {
mClock = new InternalClock();
@@ -109,12 +103,13 @@ public class ScreenUndimDetector {
/** Should be called in parent's systemReady() */
public void systemReady(Context context) {
+ mContext = context;
readValuesFromDeviceConfig();
DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
- context.getMainExecutor(),
+ mContext.getMainExecutor(),
(properties) -> onDeviceConfigChange(properties.getKeyset()));
- final PowerManager powerManager = context.getSystemService(PowerManager.class);
+ final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE,
UNDIM_DETECTOR_WAKE_LOCK);
@@ -203,36 +198,44 @@ public class ScreenUndimDetector {
}
}
- private boolean readKeepScreenOnNotificationEnabled() {
+ private boolean readKeepScreenOnEnabled() {
+ boolean defaultKeepScreenOnEnabled = mContext.getResources().getBoolean(
+ R.bool.config_defaultPreventScreenTimeoutEnabled);
return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_KEEP_SCREEN_ON_ENABLED,
- DEFAULT_KEEP_SCREEN_ON_ENABLED);
+ defaultKeepScreenOnEnabled);
}
private long readKeepScreenOnForMillis() {
+ long defaultKeepScreenOnDuration = mContext.getResources().getInteger(
+ R.integer.config_defaultPreventScreenTimeoutForMillis);
return DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_KEEP_SCREEN_ON_FOR_MILLIS,
- DEFAULT_KEEP_SCREEN_ON_FOR_MILLIS);
+ defaultKeepScreenOnDuration);
}
private int readUndimsRequired() {
+ int defaultUndimsRequired = mContext.getResources().getInteger(
+ R.integer.config_defaultUndimsRequired);
int undimsRequired = DeviceConfig.getInt(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_UNDIMS_REQUIRED,
- DEFAULT_UNDIMS_REQUIRED);
+ defaultUndimsRequired);
if (undimsRequired < 1 || undimsRequired > 5) {
Slog.e(TAG, "Provided undimsRequired=" + undimsRequired
- + " is not allowed [1, 5]; using the default=" + DEFAULT_UNDIMS_REQUIRED);
- return DEFAULT_UNDIMS_REQUIRED;
+ + " is not allowed [1, 5]; using the default=" + defaultUndimsRequired);
+ return defaultUndimsRequired;
}
return undimsRequired;
}
private long readMaxDurationBetweenUndimsMillis() {
+ long defaultMaxDurationBetweenUndimsMillis = mContext.getResources().getInteger(
+ R.integer.config_defaultMaxDurationBetweenUndimsMillis);
return DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS,
- DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS);
+ defaultMaxDurationBetweenUndimsMillis);
}
private void onDeviceConfigChange(@NonNull Set<String> keys) {
@@ -253,15 +256,16 @@ public class ScreenUndimDetector {
@VisibleForTesting
void readValuesFromDeviceConfig() {
- mKeepScreenOnEnabled = readKeepScreenOnNotificationEnabled();
+ mKeepScreenOnEnabled = readKeepScreenOnEnabled();
mKeepScreenOnForMillis = readKeepScreenOnForMillis();
mUndimsRequired = readUndimsRequired();
mMaxDurationBetweenUndimsMillis = readMaxDurationBetweenUndimsMillis();
Slog.i(TAG, "readValuesFromDeviceConfig():"
+ "\nmKeepScreenOnForMillis=" + mKeepScreenOnForMillis
- + "\nmKeepScreenOnNotificationEnabled=" + mKeepScreenOnEnabled
- + "\nmUndimsRequired=" + mUndimsRequired);
+ + "\nmKeepScreenOnEnabled=" + mKeepScreenOnEnabled
+ + "\nmUndimsRequired=" + mUndimsRequired
+ + "\nmMaxDurationBetweenUndimsMillis=" + mMaxDurationBetweenUndimsMillis);
}
diff --git a/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java b/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java
index 5563f98e8842..7cd9bdbc662c 100644
--- a/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java
+++ b/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java
@@ -374,6 +374,10 @@ public class BatteryHistoryDirectory implements BatteryStatsHistory.BatteryHisto
@SuppressWarnings("unchecked")
@Override
public List<BatteryHistoryFragment> getFragments() {
+ if (!mLock.isHeldByCurrentThread()) {
+ throw new IllegalStateException("Reading battery history without a lock");
+ }
+
ensureInitialized();
return (List<BatteryHistoryFragment>)
(List<? extends BatteryHistoryFragment>) mHistoryFiles;
@@ -443,44 +447,6 @@ public class BatteryHistoryDirectory implements BatteryStatsHistory.BatteryHisto
}
@Override
- public BatteryHistoryFragment getNextFragment(BatteryHistoryFragment current, long startTimeMs,
- long endTimeMs) {
- ensureInitialized();
-
- if (!mLock.isHeldByCurrentThread()) {
- throw new IllegalStateException("Iterating battery history without a lock");
- }
-
- int nextFileIndex = 0;
- int firstFileIndex = 0;
- // skip the last file because its data is in history buffer.
- int lastFileIndex = mHistoryFiles.size() - 2;
- for (int i = lastFileIndex; i >= 0; i--) {
- BatteryHistoryFragment fragment = mHistoryFiles.get(i);
- if (current != null && fragment.monotonicTimeMs == current.monotonicTimeMs) {
- nextFileIndex = i + 1;
- }
- if (fragment.monotonicTimeMs > endTimeMs) {
- lastFileIndex = i - 1;
- }
- if (fragment.monotonicTimeMs <= startTimeMs) {
- firstFileIndex = i;
- break;
- }
- }
-
- if (nextFileIndex < firstFileIndex) {
- nextFileIndex = firstFileIndex;
- }
-
- if (nextFileIndex <= lastFileIndex) {
- return mHistoryFiles.get(nextFileIndex);
- }
-
- return null;
- }
-
- @Override
public boolean hasCompletedFragments() {
ensureInitialized();
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index d620e98d3437..bac732637d8d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1173,12 +1173,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return;
}
- final ComponentName wpService = mWallpaper.getComponent();
// The broadcast of package update could be delayed after service disconnected. Try
// to re-bind the service for 10 seconds.
mWallpaper.mBindSource = BindSource.CONNECTION_TRY_TO_REBIND;
- if (bindWallpaperComponentLocked(
- wpService, true, false, mWallpaper, null)) {
+ boolean success;
+ if (liveWallpaperContentHandling()) {
+ success = bindWallpaperDescriptionLocked(
+ mWallpaper.getDescription(), /* force= */ true,
+ /* fromUser= */ false, mWallpaper, /* reply= */ null);
+ } else {
+ success = bindWallpaperComponentLocked(mWallpaper.getComponent(), /* force= */
+ true, /* fromUser= */false, mWallpaper, /* reply= */ null);
+ }
+ if (success) {
mWallpaper.connection.scheduleTimeoutLocked();
} else if (SystemClock.uptimeMillis() - mWallpaper.lastDiedTime
< WALLPAPER_RECONNECT_TIMEOUT_MS) {
@@ -1189,7 +1196,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Timeout
Slog.w(TAG, "Reverting to built-in wallpaper!");
clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, false, null);
- final String flattened = wpService.flattenToString();
+ final String flattened = mWallpaper.getComponent().flattenToString();
EventLog.writeEvent(EventLogTags.WP_WALLPAPER_CRASHED,
flattened.substring(0, Math.min(flattened.length(),
MAX_WALLPAPER_COMPONENT_LOG_LENGTH)));
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 58534b95bdde..1299a4d86623 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -294,19 +294,6 @@ final class AccessibilityController {
}
}
- void onAppWindowTransition(int displayId, int transition) {
- if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
- mAccessibilityTracing.logTrace(TAG + ".onAppWindowTransition",
- FLAGS_MAGNIFICATION_CALLBACK,
- "displayId=" + displayId + "; transition=" + transition);
- }
- final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
- if (displayMagnifier != null) {
- displayMagnifier.onAppWindowTransition(displayId, transition);
- }
- // Not relevant for the window observer.
- }
-
void onWMTransition(int displayId, @TransitionType int type, @TransitionFlags int flags) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(TAG + ".onWMTransition",
@@ -670,34 +657,6 @@ final class AccessibilityController {
mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED);
}
- void onAppWindowTransition(int displayId, int transition) {
- if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
- mAccessibilityTracing.logTrace(LOG_TAG + ".onAppWindowTransition",
- FLAGS_MAGNIFICATION_CALLBACK,
- "displayId=" + displayId + "; transition=" + transition);
- }
- if (DEBUG_WINDOW_TRANSITIONS) {
- Slog.i(LOG_TAG, "Window transition: "
- + AppTransition.appTransitionOldToString(transition)
- + " displayId: " + displayId);
- }
- final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
- if (!isMagnifierActivated) {
- return;
- }
- switch (transition) {
- case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN:
- case WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN:
- case WindowManager.TRANSIT_OLD_TASK_OPEN:
- case WindowManager.TRANSIT_OLD_TASK_TO_FRONT:
- case WindowManager.TRANSIT_OLD_WALLPAPER_OPEN:
- case WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE:
- case WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN: {
- mUserContextChangedNotifier.onAppWindowTransition(transition);
- }
- }
- }
-
void onWMTransition(int displayId, @TransitionType int type, @TransitionFlags int flags) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(LOG_TAG + ".onWMTransition",
@@ -734,7 +693,7 @@ final class AccessibilityController {
}
if (DEBUG_WINDOW_TRANSITIONS) {
Slog.i(LOG_TAG, "Window transition: "
- + AppTransition.appTransitionOldToString(transition)
+ + WindowManager.transitTypeToString(transition)
+ " displayId: " + windowState.getDisplayId());
}
final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 199a6d85f73f..3cd4db7d8dfc 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -673,9 +673,6 @@ final class ActivityRecord extends WindowToken {
// TODO(b/317000737): Replace it with visibility states lookup.
int mTransitionChangeFlags;
- /** Whether we need to setup the animation to animate only within the letterbox. */
- private boolean mNeedsLetterboxedAnimation;
-
/**
* @see #currentLaunchCanTurnScreenOn()
*/
@@ -5606,18 +5603,6 @@ final class ActivityRecord extends WindowToken {
commitVisibility(visible, performLayout, false /* fromTransition */);
}
- void setNeedsLetterboxedAnimation(boolean needsLetterboxedAnimation) {
- mNeedsLetterboxedAnimation = needsLetterboxedAnimation;
- }
-
- boolean isNeedsLetterboxedAnimation() {
- return mNeedsLetterboxedAnimation;
- }
-
- boolean isInLetterboxAnimation() {
- return mNeedsLetterboxedAnimation && isAnimating();
- }
-
/** Updates draw state and shows drawn windows. */
void commitFinishDrawing(SurfaceControl.Transaction t) {
boolean committed = false;
@@ -7287,10 +7272,6 @@ final class ActivityRecord extends WindowToken {
.setParent(getAnimationLeashParent())
.setName(getSurfaceControl() + " - animation-bounds")
.setCallsite("ActivityRecord.createAnimationBoundsLayer");
- if (mNeedsLetterboxedAnimation) {
- // Needs to be an effect layer to support rounded corners
- builder.setEffectLayer();
- }
final SurfaceControl boundsLayer = builder.build();
t.show(boundsLayer);
return boundsLayer;
@@ -7308,11 +7289,6 @@ final class ActivityRecord extends WindowToken {
@Override
public void onLeashAnimationStarting(Transaction t, SurfaceControl leash) {
- if (mNeedsLetterboxedAnimation) {
- updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
- mNeedsAnimationBoundsLayer = true;
- }
-
// If the animation needs to be cropped then an animation bounds layer is created as a
// child of the root pinned task or animation layer. The leash is then reparented to this
// new layer.
@@ -7325,17 +7301,6 @@ final class ActivityRecord extends WindowToken {
t.setLayer(leash, 0);
t.setLayer(mAnimationBoundsLayer, getLastLayer());
- if (mNeedsLetterboxedAnimation) {
- final int cornerRadius = mAppCompatController.getLetterboxPolicy()
- .getRoundedCornersRadius(findMainWindow());
-
- final Rect letterboxInnerBounds = new Rect();
- getLetterboxInnerBounds(letterboxInnerBounds);
-
- t.setCornerRadius(mAnimationBoundsLayer, cornerRadius)
- .setCrop(mAnimationBoundsLayer, letterboxInnerBounds);
- }
-
// Reparent leash to animation bounds layer.
t.reparent(leash, mAnimationBoundsLayer);
}
@@ -7389,10 +7354,6 @@ final class ActivityRecord extends WindowToken {
}
mNeedsAnimationBoundsLayer = false;
- if (mNeedsLetterboxedAnimation) {
- mNeedsLetterboxedAnimation = false;
- updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
- }
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 21628341ea62..cb122f2080a2 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -107,8 +107,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
&& !ActivityManager.isLowRamDeviceStatic(); // Don't support Android Go
setSnapshotEnabled(snapshotEnabled);
mSnapshotPersistQueue = persistQueue;
- mPersistInfoProvider = createPersistInfoProvider(service,
- Environment::getDataSystemCeDirectory);
+ mPersistInfoProvider = createPersistInfoProvider(service);
mPersister = new TaskSnapshotPersister(
persistQueue,
mPersistInfoProvider,
@@ -117,6 +116,11 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
initialize(new ActivitySnapshotCache());
}
+ @VisibleForTesting
+ PersistInfoProvider createPersistInfoProvider(WindowManagerService service) {
+ return createPersistInfoProvider(service, Environment::getDataSystemCeDirectory);
+ }
+
@Override
protected float initSnapshotScale() {
final float config = mService.mContext.getResources().getFloat(
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
index 6873270366ee..27511b2f1668 100644
--- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
@@ -217,7 +217,7 @@ class AppCompatLetterboxPolicy {
}
final boolean shouldShowLetterboxUi =
- (mActivityRecord.isInLetterboxAnimation() || mActivityRecord.isVisible()
+ (mActivityRecord.isVisible()
|| mActivityRecord.isVisibleRequested())
&& mainWindow.areAppWindowBoundsLetterboxed()
// Check for FLAG_SHOW_WALLPAPER explicitly instead of using
@@ -360,8 +360,7 @@ class AppCompatLetterboxPolicy {
.mAppCompatController.getReachabilityPolicy();
mLetterbox = new Letterbox(() -> mActivityRecord.makeChildSurface(null),
mActivityRecord.mWmService.mTransactionFactory,
- reachabilityPolicy, letterboxOverrides,
- this::getLetterboxParentSurface);
+ reachabilityPolicy, letterboxOverrides);
mActivityRecord.mAppCompatController.getReachabilityPolicy()
.setLetterboxInnerBoundsSupplier(mLetterbox::getInnerFrame);
}
@@ -469,15 +468,6 @@ class AppCompatLetterboxPolicy {
public boolean isFullyTransparentBarAllowed(@NonNull Rect rect) {
return !isRunning() || mLetterbox.notIntersectsOrFullyContains(rect);
}
-
- @Nullable
- private SurfaceControl getLetterboxParentSurface() {
- if (mActivityRecord.isInLetterboxAnimation()) {
- return mActivityRecord.getTask().getSurfaceControl();
- }
- return mActivityRecord.getSurfaceControl();
- }
-
}
/**
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxUtils.java b/services/core/java/com/android/server/wm/AppCompatLetterboxUtils.java
index 83d7cb7bb960..e5b61db2ef68 100644
--- a/services/core/java/com/android/server/wm/AppCompatLetterboxUtils.java
+++ b/services/core/java/com/android/server/wm/AppCompatLetterboxUtils.java
@@ -36,12 +36,7 @@ class AppCompatLetterboxUtils {
outLetterboxPosition.set(0, 0);
return;
}
- if (activity.isInLetterboxAnimation()) {
- // In this case we attach the letterbox to the task instead of the activity.
- activity.getTask().getPosition(outLetterboxPosition);
- } else {
- activity.getPosition(outLetterboxPosition);
- }
+ activity.getPosition(outLetterboxPosition);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
index 8165638d4bda..92b91464312e 100644
--- a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
+++ b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
@@ -58,7 +58,7 @@ class AppCompatRoundedCorners {
@VisibleForTesting
@Nullable
Rect getCropBoundsIfNeeded(@NonNull final WindowState mainWindow) {
- if (!requiresRoundedCorners(mainWindow) || mActivityRecord.isInLetterboxAnimation()) {
+ if (!requiresRoundedCorners(mainWindow)) {
// We don't want corner radius on the window.
// In the case the ActivityRecord requires a letterboxed animation we never want
// rounded corners on the window because rounded corners are applied at the
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
deleted file mode 100644
index 12d4a210400c..000000000000
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ /dev/null
@@ -1,1587 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.view.WindowManager.LayoutParams;
-import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_CLOSE;
-import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
-import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
-import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
-import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
-import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-import static android.view.WindowManager.TRANSIT_NONE;
-import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_RELAUNCH;
-import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
-import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
-import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
-import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
-import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
-import static android.view.WindowManager.TRANSIT_OLD_NONE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_FRONT;
-import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_UNSET;
-import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_OPEN;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_RELAUNCH;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
-
-import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
-import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
-import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_APP_TRANSITIONS_ANIM;
-import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE;
-import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
-import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM;
-import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
-
-import android.annotation.ColorInt;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.hardware.HardwareBuffer;
-import android.os.Binder;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.proto.ProtoOutputStream;
-import android.view.AppTransitionAnimationSpec;
-import android.view.IAppTransitionAnimationSpecsFuture;
-import android.view.RemoteAnimationAdapter;
-import android.view.WindowManager.TransitionFlags;
-import android.view.WindowManager.TransitionOldType;
-import android.view.WindowManager.TransitionType;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.TranslateAnimation;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.ProtoLog;
-import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.util.DumpUtils.Dump;
-import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.internal.util.function.pooled.PooledPredicate;
-import com.android.server.wm.ActivityRecord.CustomAppTransition;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-// State management of app transitions. When we are preparing for a
-// transition, mNextAppTransition will be the kind of transition to
-// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
-// mOpeningApps and mClosingApps are the lists of tokens that will be
-// made visible or hidden at the next transition.
-public class AppTransition implements Dump {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "AppTransition" : TAG_WM;
-
- static final int DEFAULT_APP_TRANSITION_DURATION = 336;
-
- /**
- * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
- * involved, to make it more understandable.
- */
- private static final long APP_TRANSITION_TIMEOUT_MS = 5000;
- static final int MAX_APP_TRANSITION_DURATION = 3 * 1000; // 3 secs.
-
- private final Context mContext;
- private final WindowManagerService mService;
- private final DisplayContent mDisplayContent;
-
- @VisibleForTesting
- final TransitionAnimation mTransitionAnimation;
-
- private @TransitionFlags int mNextAppTransitionFlags = 0;
- private final ArrayList<Integer> mNextAppTransitionRequests = new ArrayList<>();
- private @TransitionOldType int mLastUsedAppTransition = TRANSIT_OLD_UNSET;
- private String mLastOpeningApp;
- private String mLastClosingApp;
- private String mLastChangingApp;
-
- private static final int NEXT_TRANSIT_TYPE_NONE = 0;
- private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1;
- private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2;
- private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3;
- private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
- private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
- private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
- private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
- private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8;
-
- /**
- * Refers to the transition to activity started by using {@link
- * android.content.pm.crossprofile.CrossProfileApps#startMainActivity(ComponentName, UserHandle)
- * }.
- */
- private static final int NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS = 9;
- private static final int NEXT_TRANSIT_TYPE_REMOTE = 10;
-
- private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
- private boolean mNextAppTransitionOverrideRequested;
-
- private String mNextAppTransitionPackage;
- // Used for thumbnail transitions. True if we're scaling up, false if scaling down
- private boolean mNextAppTransitionScaleUp;
- private IRemoteCallback mNextAppTransitionCallback;
- private IRemoteCallback mNextAppTransitionFutureCallback;
- private IRemoteCallback mAnimationFinishedCallback;
- private int mNextAppTransitionEnter;
- private int mNextAppTransitionExit;
- private @ColorInt int mNextAppTransitionBackgroundColor;
- private int mNextAppTransitionInPlace;
- private boolean mNextAppTransitionIsSync;
-
- // Keyed by WindowContainer hashCode.
- private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
- = new SparseArray<>();
- private IAppTransitionAnimationSpecsFuture mNextAppTransitionAnimationsSpecsFuture;
- private boolean mNextAppTransitionAnimationsSpecsPending;
- private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec;
-
- private final Rect mTmpRect = new Rect();
-
- private final static int APP_STATE_IDLE = 0;
- private final static int APP_STATE_READY = 1;
- private final static int APP_STATE_RUNNING = 2;
- private final static int APP_STATE_TIMEOUT = 3;
- private int mAppTransitionState = APP_STATE_IDLE;
-
- private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
- private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor();
-
- private final int mDefaultWindowAnimationStyleResId;
- private boolean mOverrideTaskTransition;
-
- final Handler mHandler;
- final Runnable mHandleAppTransitionTimeoutRunnable = () -> handleAppTransitionTimeout();
-
- AppTransition(Context context, WindowManagerService service, DisplayContent displayContent) {
- mContext = context;
- mService = service;
- mHandler = new Handler(service.mH.getLooper());
- mDisplayContent = displayContent;
- mTransitionAnimation = new TransitionAnimation(
- context, ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG), TAG);
-
- final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes(
- com.android.internal.R.styleable.Window);
- mDefaultWindowAnimationStyleResId = windowStyle.getResourceId(
- com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
- windowStyle.recycle();
- }
-
- boolean isTransitionSet() {
- return !mNextAppTransitionRequests.isEmpty();
- }
-
- boolean isUnoccluding() {
- return mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_UNOCCLUDE);
- }
-
- boolean transferFrom(AppTransition other) {
- mNextAppTransitionRequests.addAll(other.mNextAppTransitionRequests);
- return prepare();
- }
-
- void setLastAppTransition(@TransitionOldType int transit, ActivityRecord openingApp,
- ActivityRecord closingApp, ActivityRecord changingApp) {
- mLastUsedAppTransition = transit;
- mLastOpeningApp = "" + openingApp;
- mLastClosingApp = "" + closingApp;
- mLastChangingApp = "" + changingApp;
- }
-
- boolean isReady() {
- return mAppTransitionState == APP_STATE_READY
- || mAppTransitionState == APP_STATE_TIMEOUT;
- }
-
- void setReady() {
- setAppTransitionState(APP_STATE_READY);
- fetchAppTransitionSpecsFromFuture();
- }
-
- boolean isRunning() {
- return mAppTransitionState == APP_STATE_RUNNING;
- }
-
- void setIdle() {
- setAppTransitionState(APP_STATE_IDLE);
- }
-
- boolean isIdle() {
- return mAppTransitionState == APP_STATE_IDLE;
- }
-
- boolean isTimeout() {
- return mAppTransitionState == APP_STATE_TIMEOUT;
- }
-
- void setTimeout() {
- setAppTransitionState(APP_STATE_TIMEOUT);
- }
-
- /**
- * Gets the animation overridden by app via {@link #overridePendingAppTransition}.
- */
- @Nullable
- Animation getNextAppRequestedAnimation(boolean enter) {
- final Animation a = mTransitionAnimation.loadAppTransitionAnimation(
- mNextAppTransitionPackage,
- enter ? mNextAppTransitionEnter : mNextAppTransitionExit);
- if (mNextAppTransitionBackgroundColor != 0 && a != null) {
- a.setBackdropColor(mNextAppTransitionBackgroundColor);
- }
- return a;
- }
-
- /**
- * Gets the animation background color overridden by app via
- * {@link #overridePendingAppTransition}.
- */
- @ColorInt int getNextAppTransitionBackgroundColor() {
- return mNextAppTransitionBackgroundColor;
- }
-
- @VisibleForTesting
- boolean isNextAppTransitionOverrideRequested() {
- return mNextAppTransitionOverrideRequested;
- }
-
- HardwareBuffer getAppTransitionThumbnailHeader(WindowContainer container) {
- AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
- container.hashCode());
- if (spec == null) {
- spec = mDefaultNextAppTransitionAnimationSpec;
- }
- return spec != null ? spec.buffer : null;
- }
-
- /** Returns whether the next thumbnail transition is aspect scaled up. */
- boolean isNextThumbnailTransitionAspectScaled() {
- return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
- mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
- }
-
- /** Returns whether the next thumbnail transition is scaling up. */
- boolean isNextThumbnailTransitionScaleUp() {
- return mNextAppTransitionScaleUp;
- }
-
- boolean isNextAppTransitionThumbnailUp() {
- return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
- mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP;
- }
-
- boolean isNextAppTransitionThumbnailDown() {
- return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN ||
- mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
- }
-
- boolean isNextAppTransitionOpenCrossProfileApps() {
- return mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS;
- }
-
- /**
- * @return true if and only if we are currently fetching app transition specs from the future
- * passed into {@link #overridePendingAppTransitionMultiThumbFuture}
- */
- boolean isFetchingAppTransitionsSpecs() {
- return mNextAppTransitionAnimationsSpecsPending;
- }
-
- private boolean prepare() {
- if (!isRunning()) {
- setAppTransitionState(APP_STATE_IDLE);
- notifyAppTransitionPendingLocked();
- return true;
- }
- return false;
- }
-
- /**
- * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
- * layout pass needs to be done
- */
- int goodToGo(@TransitionOldType int transit, ActivityRecord topOpeningApp) {
- mNextAppTransitionFlags = 0;
- mNextAppTransitionRequests.clear();
- setAppTransitionState(APP_STATE_RUNNING);
- final WindowContainer wc =
- topOpeningApp != null ? topOpeningApp.getAnimatingContainer() : null;
- final AnimationAdapter topOpeningAnim = wc != null ? wc.getAnimation() : null;
-
- int redoLayout = notifyAppTransitionStartingLocked(
- topOpeningAnim != null
- ? topOpeningAnim.getStatusBarTransitionsStartTime()
- : SystemClock.uptimeMillis(),
- AnimationAdapter.STATUS_BAR_TRANSITION_DURATION);
-
- if ((isTaskOpenTransitOld(transit) || transit == TRANSIT_OLD_WALLPAPER_CLOSE)
- && topOpeningAnim != null) {
- if (mDisplayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()) {
- final NavBarFadeAnimationController controller =
- new NavBarFadeAnimationController(mDisplayContent);
- // For remote animation case, the nav bar fades out and in is controlled by the
- // remote side. For non-remote animation case, we play the fade out/in animation
- // here. We play the nav bar fade-out animation when the app transition animation
- // starts and play the fade-in animation sequentially once the fade-out is finished.
- controller.fadeOutAndInSequentially(topOpeningAnim.getDurationHint(),
- null /* fadeOutParent */, topOpeningApp.getSurfaceControl());
- }
- }
- return redoLayout;
- }
-
- void clear() {
- clear(true /* clearAppOverride */);
- }
-
- private void clear(boolean clearAppOverride) {
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
- mNextAppTransitionOverrideRequested = false;
- mNextAppTransitionAnimationsSpecs.clear();
- mNextAppTransitionAnimationsSpecsFuture = null;
- mDefaultNextAppTransitionAnimationSpec = null;
- mAnimationFinishedCallback = null;
- mOverrideTaskTransition = false;
- mNextAppTransitionIsSync = false;
- if (clearAppOverride) {
- mNextAppTransitionPackage = null;
- mNextAppTransitionEnter = 0;
- mNextAppTransitionExit = 0;
- mNextAppTransitionBackgroundColor = 0;
- }
- }
-
- void freeze() {
- final boolean keyguardGoingAwayCancelled = mNextAppTransitionRequests.contains(
- TRANSIT_KEYGUARD_GOING_AWAY);
-
- mNextAppTransitionRequests.clear();
- clear();
- setReady();
- notifyAppTransitionCancelledLocked(keyguardGoingAwayCancelled);
- }
-
- private void setAppTransitionState(int state) {
- mAppTransitionState = state;
- updateBooster();
- }
-
- /**
- * Updates whether we currently boost wm locked sections and the animation thread. We want to
- * boost the priorities to a more important value whenever an app transition is going to happen
- * soon or an app transition is running.
- */
- void updateBooster() {
- WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning(needsBoosting());
- }
-
- private boolean needsBoosting() {
- return !mNextAppTransitionRequests.isEmpty()
- || mAppTransitionState == APP_STATE_READY
- || mAppTransitionState == APP_STATE_RUNNING;
- }
-
- void registerListenerLocked(AppTransitionListener listener) {
- mListeners.add(listener);
- }
-
- void unregisterListener(AppTransitionListener listener) {
- mListeners.remove(listener);
- }
-
- public void notifyAppTransitionFinishedLocked(IBinder token) {
- for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionFinishedLocked(token);
- }
- }
-
- private void notifyAppTransitionPendingLocked() {
- for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionPendingLocked();
- }
- }
-
- private void notifyAppTransitionCancelledLocked(boolean keyguardGoingAwayCancelled) {
- for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionCancelledLocked(keyguardGoingAwayCancelled);
- }
- }
-
- private void notifyAppTransitionTimeoutLocked() {
- for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionTimeoutLocked();
- }
- }
-
- private int notifyAppTransitionStartingLocked(long statusBarAnimationStartTime,
- long statusBarAnimationDuration) {
- int redoLayout = 0;
- for (int i = 0; i < mListeners.size(); i++) {
- redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(
- statusBarAnimationStartTime, statusBarAnimationDuration);
- }
- return redoLayout;
- }
-
- @VisibleForTesting
- int getDefaultWindowAnimationStyleResId() {
- return mDefaultWindowAnimationStyleResId;
- }
-
- /** Returns window animation style ID from {@link LayoutParams} or from system in some cases */
- @VisibleForTesting
- int getAnimationStyleResId(@NonNull LayoutParams lp) {
- return mTransitionAnimation.getAnimationStyleResId(lp);
- }
-
- @VisibleForTesting
- @Nullable
- Animation loadAnimationSafely(Context context, int resId) {
- return TransitionAnimation.loadAnimationSafely(context, resId, TAG);
- }
-
- private static int mapOpenCloseTransitTypes(int transit, boolean enter) {
- int animAttr = 0;
- switch (transit) {
- case TRANSIT_OLD_ACTIVITY_OPEN:
- case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN:
- animAttr = enter
- ? WindowAnimation_activityOpenEnterAnimation
- : WindowAnimation_activityOpenExitAnimation;
- break;
- case TRANSIT_OLD_ACTIVITY_CLOSE:
- case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE:
- animAttr = enter
- ? WindowAnimation_activityCloseEnterAnimation
- : WindowAnimation_activityCloseExitAnimation;
- break;
- case TRANSIT_OLD_TASK_OPEN:
- animAttr = enter
- ? WindowAnimation_taskOpenEnterAnimation
- : WindowAnimation_taskOpenExitAnimation;
- break;
- case TRANSIT_OLD_TASK_CLOSE:
- animAttr = enter
- ? WindowAnimation_taskCloseEnterAnimation
- : WindowAnimation_taskCloseExitAnimation;
- break;
- case TRANSIT_OLD_TASK_TO_FRONT:
- animAttr = enter
- ? WindowAnimation_taskToFrontEnterAnimation
- : WindowAnimation_taskToFrontExitAnimation;
- break;
- case TRANSIT_OLD_TASK_TO_BACK:
- animAttr = enter
- ? WindowAnimation_taskToBackEnterAnimation
- : WindowAnimation_taskToBackExitAnimation;
- break;
- case TRANSIT_OLD_WALLPAPER_OPEN:
- animAttr = enter
- ? WindowAnimation_wallpaperOpenEnterAnimation
- : WindowAnimation_wallpaperOpenExitAnimation;
- break;
- case TRANSIT_OLD_WALLPAPER_CLOSE:
- animAttr = enter
- ? WindowAnimation_wallpaperCloseEnterAnimation
- : WindowAnimation_wallpaperCloseExitAnimation;
- break;
- case TRANSIT_OLD_WALLPAPER_INTRA_OPEN:
- animAttr = enter
- ? WindowAnimation_wallpaperIntraOpenEnterAnimation
- : WindowAnimation_wallpaperIntraOpenExitAnimation;
- break;
- case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE:
- animAttr = enter
- ? WindowAnimation_wallpaperIntraCloseEnterAnimation
- : WindowAnimation_wallpaperIntraCloseExitAnimation;
- break;
- case TRANSIT_OLD_TASK_OPEN_BEHIND:
- animAttr = enter
- ? WindowAnimation_launchTaskBehindSourceAnimation
- : WindowAnimation_launchTaskBehindTargetAnimation;
- break;
- // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
- // need new TaskFragment transition.
- case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
- animAttr = enter
- ? WindowAnimation_activityOpenEnterAnimation
- : WindowAnimation_activityOpenExitAnimation;
- break;
- // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
- // need new TaskFragment transition.
- case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
- animAttr = enter
- ? WindowAnimation_activityCloseEnterAnimation
- : WindowAnimation_activityCloseExitAnimation;
- break;
- case TRANSIT_OLD_DREAM_ACTIVITY_OPEN:
- animAttr = enter
- ? WindowAnimation_dreamActivityOpenEnterAnimation
- : WindowAnimation_dreamActivityOpenExitAnimation;
- break;
- case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE:
- animAttr = enter
- ? 0
- : WindowAnimation_dreamActivityCloseExitAnimation;
- break;
- }
-
- return animAttr;
- }
-
- @Nullable
- Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
- return mTransitionAnimation.loadAnimationAttr(lp, animAttr, transit);
- }
-
- private void getDefaultNextAppTransitionStartRect(Rect rect) {
- if (mDefaultNextAppTransitionAnimationSpec == null ||
- mDefaultNextAppTransitionAnimationSpec.rect == null) {
- Slog.e(TAG, "Starting rect for app requested, but none available", new Throwable());
- rect.setEmpty();
- } else {
- rect.set(mDefaultNextAppTransitionAnimationSpec.rect);
- }
- }
-
- private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height,
- HardwareBuffer buffer) {
- mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
- buffer, new Rect(left, top, left + width, top + height));
- }
-
- /**
- * Creates an overlay with a background color and a thumbnail for the cross profile apps
- * animation.
- */
- HardwareBuffer createCrossProfileAppsThumbnail(
- Drawable thumbnailDrawable, Rect frame) {
- return mTransitionAnimation.createCrossProfileAppsThumbnail(thumbnailDrawable, frame);
- }
-
- Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) {
- return mTransitionAnimation.createCrossProfileAppsThumbnailAnimationLocked(appRect);
- }
-
- /**
- * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
- * when a thumbnail is specified with the pending animation override.
- */
- Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
- HardwareBuffer thumbnailHeader, WindowContainer container, int orientation) {
- AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
- container.hashCode());
- return mTransitionAnimation.createThumbnailAspectScaleAnimationLocked(appRect,
- contentInsets, thumbnailHeader, orientation, spec != null ? spec.rect : null,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null,
- mNextAppTransitionScaleUp);
- }
-
- private AnimationSet createAspectScaledThumbnailFreeformAnimationLocked(Rect sourceFrame,
- Rect destFrame, @Nullable Rect surfaceInsets, boolean enter) {
- final float sourceWidth = sourceFrame.width();
- final float sourceHeight = sourceFrame.height();
- final float destWidth = destFrame.width();
- final float destHeight = destFrame.height();
- final float scaleH = enter ? sourceWidth / destWidth : destWidth / sourceWidth;
- final float scaleV = enter ? sourceHeight / destHeight : destHeight / sourceHeight;
- AnimationSet set = new AnimationSet(true);
- final int surfaceInsetsH = surfaceInsets == null
- ? 0 : surfaceInsets.left + surfaceInsets.right;
- final int surfaceInsetsV = surfaceInsets == null
- ? 0 : surfaceInsets.top + surfaceInsets.bottom;
- // We want the scaling to happen from the center of the surface. In order to achieve that,
- // we need to account for surface insets that will be used to enlarge the surface.
- final float scaleHCenter = ((enter ? destWidth : sourceWidth) + surfaceInsetsH) / 2;
- final float scaleVCenter = ((enter ? destHeight : sourceHeight) + surfaceInsetsV) / 2;
- final ScaleAnimation scale = enter ?
- new ScaleAnimation(scaleH, 1, scaleV, 1, scaleHCenter, scaleVCenter)
- : new ScaleAnimation(1, scaleH, 1, scaleV, scaleHCenter, scaleVCenter);
- final int sourceHCenter = sourceFrame.left + sourceFrame.width() / 2;
- final int sourceVCenter = sourceFrame.top + sourceFrame.height() / 2;
- final int destHCenter = destFrame.left + destFrame.width() / 2;
- final int destVCenter = destFrame.top + destFrame.height() / 2;
- final int fromX = enter ? sourceHCenter - destHCenter : destHCenter - sourceHCenter;
- final int fromY = enter ? sourceVCenter - destVCenter : destVCenter - sourceVCenter;
- final TranslateAnimation translation = enter ? new TranslateAnimation(fromX, 0, fromY, 0)
- : new TranslateAnimation(0, fromX, 0, fromY);
- set.addAnimation(scale);
- set.addAnimation(translation);
- setAppTransitionFinishedCallbackIfNeeded(set);
- return set;
- }
-
- /**
- * @return true if and only if the first frame of the transition can be skipped, i.e. the first
- * frame of the transition doesn't change the visuals on screen, so we can start
- * directly with the second one
- */
- boolean canSkipFirstFrame() {
- return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
- && !mNextAppTransitionOverrideRequested
- && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
- && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
- && !mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY);
- }
-
- /**
- *
- * @param frame These are the bounds of the window when it finishes the animation. This is where
- * the animation must usually finish in entrance animation, as the next frame will
- * display the window at these coordinates. In case of exit animation, this is
- * where the animation must start, as the frame before the animation is displaying
- * the window at these bounds.
- * @param insets Knowing where the window will be positioned is not enough. Some parts of the
- * window might be obscured, usually by the system windows (status bar and
- * navigation bar) and we use content insets to convey that information. This
- * usually affects the animation aspects vertically, as the system decoration is
- * at the top and the bottom. For example when we animate from full screen to
- * recents, we want to exclude the covered parts, because they won't match the
- * thumbnail after the last frame is executed.
- * @param surfaceInsets In rare situation the surface is larger than the content and we need to
- * know about this to make the animation frames match. We currently use
- * this for freeform windows, which have larger surfaces to display
- * shadows. When we animate them from recents, we want to match the content
- * to the recents thumbnail and hence need to account for the surface being
- * bigger.
- */
- @Nullable
- Animation loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode,
- int orientation, Rect frame, Rect displayFrame, Rect insets,
- @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
- boolean freeform, WindowContainer container) {
-
- final boolean canCustomizeAppTransition = container.canCustomizeAppTransition();
-
- if (mNextAppTransitionOverrideRequested) {
- if (canCustomizeAppTransition || mOverrideTaskTransition) {
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
- } else {
- ProtoLog.e(WM_DEBUG_APP_TRANSITIONS_ANIM, "applyAnimation: "
- + " override requested, but it is prohibited by policy.");
- }
- }
-
- Animation a;
- if (isKeyguardGoingAwayTransitOld(transit) && enter) {
- a = mTransitionAnimation.loadKeyguardExitAnimation(mNextAppTransitionFlags,
- transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER);
- } else if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE
- || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM) {
- a = null;
- } else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE && !enter) {
- a = mTransitionAnimation.loadKeyguardUnoccludeAnimation();
- } else if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) {
- a = null;
- } else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_OPEN
- || transit == TRANSIT_OLD_TASK_OPEN
- || transit == TRANSIT_OLD_TASK_TO_FRONT)) {
- a = mTransitionAnimation.loadVoiceActivityOpenAnimation(enter);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
- appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_CLOSE
- || transit == TRANSIT_OLD_TASK_CLOSE
- || transit == TRANSIT_OLD_TASK_TO_BACK)) {
- a = mTransitionAnimation.loadVoiceActivityExitAnimation(enter);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
- appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (transit == TRANSIT_OLD_ACTIVITY_RELAUNCH) {
- a = mTransitionAnimation.createRelaunchAnimation(frame, insets,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s transit=%s Callers=%s", a,
- appTransitionOldToString(transit), Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
- a = getNextAppRequestedAnimation(enter);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
- + "isEntrance=%b Callers=%s",
- a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
- a = mTransitionAnimation.loadAppTransitionAnimation(
- mNextAppTransitionPackage, mNextAppTransitionInPlace);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE "
- + "transit=%s Callers=%s",
- a, appTransitionOldToString(transit), Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
- a = mTransitionAnimation.createClipRevealAnimationLockedCompat(
- transit, enter, frame, displayFrame,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL "
- + "transit=%s Callers=%s",
- a, appTransitionOldToString(transit), Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
- a = mTransitionAnimation.createScaleUpAnimationLockedCompat(transit, enter, frame,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s "
- + "isEntrance=%s Callers=%s",
- a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
- mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
- mNextAppTransitionScaleUp =
- (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
- final HardwareBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container);
- a = mTransitionAnimation.createThumbnailEnterExitAnimationLockedCompat(enter,
- mNextAppTransitionScaleUp, frame, transit, thumbnailHeader,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
- + "Callers=%s",
- a, mNextAppTransitionScaleUp
- ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN",
- appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
- mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
- mNextAppTransitionScaleUp =
- (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
- AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
- container.hashCode());
- a = mTransitionAnimation.createAspectScaledThumbnailEnterExitAnimationLocked(enter,
- mNextAppTransitionScaleUp, orientation, transit, frame, insets, surfaceInsets,
- stableInsets, freeform, spec != null ? spec.rect : null,
- mDefaultNextAppTransitionAnimationSpec != null
- ? mDefaultNextAppTransitionAnimationSpec.rect : null);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
- + "Callers=%s",
- a, mNextAppTransitionScaleUp
- ? "ANIM_THUMBNAIL_ASPECT_SCALE_UP"
- : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN",
- appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) {
- a = mTransitionAnimation.loadCrossProfileAppEnterAnimation();
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: "
- + "anim=%s transit=%s isEntrance=true Callers=%s",
- a, appTransitionOldToString(transit), Debug.getCallers(3));
- } else if (isChangeTransitOld(transit)) {
- // In the absence of a specific adapter, we just want to keep everything stationary.
- a = new AlphaAnimation(1.f, 1.f);
- a.setDuration(WindowChangeAnimationSpec.ANIMATION_DURATION);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
- a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
- } else {
- int animAttr = mapOpenCloseTransitTypes(transit, enter);
- if (animAttr != 0) {
- final CustomAppTransition customAppTransition =
- getCustomAppTransition(animAttr, container);
- if (customAppTransition != null) {
- a = loadCustomActivityAnimation(customAppTransition, enter, container);
- } else {
- if (canCustomizeAppTransition) {
- a = loadAnimationAttr(lp, animAttr, transit);
- } else {
- a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, transit);
- }
- }
- } else {
- a = null;
- }
-
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b "
- + " canCustomizeAppTransition=%b Callers=%s",
- a, animAttr, appTransitionOldToString(transit), enter,
- canCustomizeAppTransition, Debug.getCallers(3));
- }
- setAppTransitionFinishedCallbackIfNeeded(a);
-
- return a;
- }
-
- CustomAppTransition getCustomAppTransition(int animAttr, WindowContainer container) {
- ActivityRecord customAnimationSource = container.asActivityRecord();
- if (customAnimationSource == null) {
- return null;
- }
-
- // Only top activity can customize activity animation.
- // If the animation is for the one below, try to get from the above activity.
- if (animAttr == WindowAnimation_activityOpenExitAnimation
- || animAttr == WindowAnimation_activityCloseEnterAnimation) {
- customAnimationSource = customAnimationSource.getTask()
- .getActivityAbove(customAnimationSource);
- if (customAnimationSource == null) {
- return null;
- }
- }
- switch (animAttr) {
- case WindowAnimation_activityOpenEnterAnimation:
- case WindowAnimation_activityOpenExitAnimation:
- return customAnimationSource.getCustomAnimation(true /* open */);
- case WindowAnimation_activityCloseEnterAnimation:
- case WindowAnimation_activityCloseExitAnimation:
- return customAnimationSource.getCustomAnimation(false /* open */);
- }
- return null;
- }
- private Animation loadCustomActivityAnimation(@NonNull CustomAppTransition custom,
- boolean enter, WindowContainer container) {
- final ActivityRecord customAnimationSource = container.asActivityRecord();
- final Animation a = mTransitionAnimation.loadAppTransitionAnimation(
- customAnimationSource.packageName, enter
- ? custom.mEnterAnim : custom.mExitAnim);
- if (a != null && custom.mBackgroundColor != 0) {
- a.setBackdropColor(custom.mBackgroundColor);
- a.setShowBackdrop(true);
- }
- return a;
- }
-
- int getAppRootTaskClipMode() {
- return mNextAppTransitionRequests.contains(TRANSIT_RELAUNCH)
- || mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY)
- || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
- ? ROOT_TASK_CLIP_NONE
- : ROOT_TASK_CLIP_AFTER_ANIM;
- }
-
- @TransitionFlags
- public int getTransitFlags() {
- return mNextAppTransitionFlags;
- }
-
- void postAnimationCallback() {
- if (mNextAppTransitionCallback != null) {
- mHandler.sendMessage(PooledLambda.obtainMessage(AppTransition::doAnimationCallback,
- mNextAppTransitionCallback));
- mNextAppTransitionCallback = null;
- }
- }
-
- void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
- @ColorInt int backgroundColor, IRemoteCallback startedCallback,
- IRemoteCallback endedCallback, boolean overrideTaskTransaction) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionOverrideRequested = true;
- mNextAppTransitionPackage = packageName;
- mNextAppTransitionEnter = enterAnim;
- mNextAppTransitionExit = exitAnim;
- mNextAppTransitionBackgroundColor = backgroundColor;
- postAnimationCallback();
- mNextAppTransitionCallback = startedCallback;
- mAnimationFinishedCallback = endedCallback;
- mOverrideTaskTransition = overrideTaskTransaction;
- }
- }
-
- void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
- int startHeight) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
- putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
- postAnimationCallback();
- }
- }
-
- void overridePendingAppTransitionClipReveal(int startX, int startY,
- int startWidth, int startHeight) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
- putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
- postAnimationCallback();
- }
- }
-
- void overridePendingAppTransitionThumb(HardwareBuffer srcThumb, int startX, int startY,
- IRemoteCallback startedCallback, boolean scaleUp) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
- : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
- mNextAppTransitionScaleUp = scaleUp;
- putDefaultNextAppTransitionCoordinates(startX, startY, 0, 0, srcThumb);
- postAnimationCallback();
- mNextAppTransitionCallback = startedCallback;
- }
- }
-
- void overridePendingAppTransitionAspectScaledThumb(HardwareBuffer srcThumb, int startX,
- int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
- boolean scaleUp) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
- : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
- mNextAppTransitionScaleUp = scaleUp;
- putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight,
- srcThumb);
- postAnimationCallback();
- mNextAppTransitionCallback = startedCallback;
- }
- }
-
- void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
- IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
- boolean scaleUp) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
- : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
- mNextAppTransitionScaleUp = scaleUp;
- if (specs != null) {
- for (int i = 0; i < specs.length; i++) {
- AppTransitionAnimationSpec spec = specs[i];
- if (spec != null) {
- final PooledPredicate p = PooledLambda.obtainPredicate(
- Task::isTaskId, PooledLambda.__(Task.class), spec.taskId);
- final WindowContainer container = mDisplayContent.getTask(p);
- p.recycle();
- if (container == null) {
- continue;
- }
- mNextAppTransitionAnimationsSpecs.put(container.hashCode(), spec);
- if (i == 0) {
- // In full screen mode, the transition code depends on the default spec
- // to be set.
- Rect rect = spec.rect;
- putDefaultNextAppTransitionCoordinates(rect.left, rect.top,
- rect.width(), rect.height(), spec.buffer);
- }
- }
- }
- }
- postAnimationCallback();
- mNextAppTransitionCallback = onAnimationStartedCallback;
- mAnimationFinishedCallback = onAnimationFinishedCallback;
- }
- }
-
- void overridePendingAppTransitionMultiThumbFuture(
- IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
- boolean scaleUp) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
- : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
- mNextAppTransitionAnimationsSpecsFuture = specsFuture;
- mNextAppTransitionScaleUp = scaleUp;
- mNextAppTransitionFutureCallback = callback;
- if (isReady()) {
- fetchAppTransitionSpecsFromFuture();
- }
- }
- }
-
- void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
- overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */,
- false /* isActivityEmbedding*/);
- }
-
- void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
- boolean sync, boolean isActivityEmbedding) {
- }
-
- void overrideInPlaceAppTransition(String packageName, int anim) {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
- mNextAppTransitionPackage = packageName;
- mNextAppTransitionInPlace = anim;
- }
- }
-
- /**
- * @see {@link #NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS}
- */
- void overridePendingAppTransitionStartCrossProfileApps() {
- if (canOverridePendingAppTransition()) {
- clear();
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS;
- postAnimationCallback();
- }
- }
-
- private boolean canOverridePendingAppTransition() {
- // Remote animations always take precedence
- return isTransitionSet() && mNextAppTransitionType != NEXT_TRANSIT_TYPE_REMOTE;
- }
-
- /**
- * If a future is set for the app transition specs, fetch it in another thread.
- */
- private void fetchAppTransitionSpecsFromFuture() {
- if (mNextAppTransitionAnimationsSpecsFuture != null) {
- mNextAppTransitionAnimationsSpecsPending = true;
- final IAppTransitionAnimationSpecsFuture future
- = mNextAppTransitionAnimationsSpecsFuture;
- mNextAppTransitionAnimationsSpecsFuture = null;
- mDefaultExecutor.execute(() -> {
- AppTransitionAnimationSpec[] specs = null;
- try {
- Binder.allowBlocking(future.asBinder());
- specs = future.get();
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to fetch app transition specs: " + e);
- }
- synchronized (mService.mGlobalLock) {
- mNextAppTransitionAnimationsSpecsPending = false;
- overridePendingAppTransitionMultiThumb(specs,
- mNextAppTransitionFutureCallback, null /* finishedCallback */,
- mNextAppTransitionScaleUp);
- mNextAppTransitionFutureCallback = null;
- mService.requestTraversal();
- }
- });
- }
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("mNextAppTransitionRequests=[");
-
- boolean separator = false;
- for (Integer transit : mNextAppTransitionRequests) {
- if (separator) {
- sb.append(", ");
- }
- sb.append(appTransitionToString(transit));
- separator = true;
- }
- sb.append("]");
- sb.append(", mNextAppTransitionFlags="
- + appTransitionFlagsToString(mNextAppTransitionFlags));
- return sb.toString();
- }
-
- /**
- * Returns the human readable name of a old window transition.
- *
- * @param transition The old window transition.
- * @return The transition symbolic name.
- */
- public static String appTransitionOldToString(@TransitionOldType int transition) {
- switch (transition) {
- case TRANSIT_OLD_UNSET: {
- return "TRANSIT_OLD_UNSET";
- }
- case TRANSIT_OLD_NONE: {
- return "TRANSIT_OLD_NONE";
- }
- case TRANSIT_OLD_ACTIVITY_OPEN: {
- return "TRANSIT_OLD_ACTIVITY_OPEN";
- }
- case TRANSIT_OLD_ACTIVITY_CLOSE: {
- return "TRANSIT_OLD_ACTIVITY_CLOSE";
- }
- case TRANSIT_OLD_TASK_OPEN: {
- return "TRANSIT_OLD_TASK_OPEN";
- }
- case TRANSIT_OLD_TASK_CLOSE: {
- return "TRANSIT_OLD_TASK_CLOSE";
- }
- case TRANSIT_OLD_TASK_TO_FRONT: {
- return "TRANSIT_OLD_TASK_TO_FRONT";
- }
- case TRANSIT_OLD_TASK_TO_BACK: {
- return "TRANSIT_OLD_TASK_TO_BACK";
- }
- case TRANSIT_OLD_WALLPAPER_CLOSE: {
- return "TRANSIT_OLD_WALLPAPER_CLOSE";
- }
- case TRANSIT_OLD_WALLPAPER_OPEN: {
- return "TRANSIT_OLD_WALLPAPER_OPEN";
- }
- case TRANSIT_OLD_WALLPAPER_INTRA_OPEN: {
- return "TRANSIT_OLD_WALLPAPER_INTRA_OPEN";
- }
- case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE: {
- return "TRANSIT_OLD_WALLPAPER_INTRA_CLOSE";
- }
- case TRANSIT_OLD_TASK_OPEN_BEHIND: {
- return "TRANSIT_OLD_TASK_OPEN_BEHIND";
- }
- case TRANSIT_OLD_ACTIVITY_RELAUNCH: {
- return "TRANSIT_OLD_ACTIVITY_RELAUNCH";
- }
- case TRANSIT_OLD_KEYGUARD_GOING_AWAY: {
- return "TRANSIT_OLD_KEYGUARD_GOING_AWAY";
- }
- case TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER: {
- return "TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER";
- }
- case TRANSIT_OLD_KEYGUARD_OCCLUDE: {
- return "TRANSIT_OLD_KEYGUARD_OCCLUDE";
- }
- case TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM: {
- return "TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM";
- }
- case TRANSIT_OLD_KEYGUARD_UNOCCLUDE: {
- return "TRANSIT_OLD_KEYGUARD_UNOCCLUDE";
- }
- case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN: {
- return "TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN";
- }
- case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE: {
- return "TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE";
- }
- case TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE: {
- return "TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE";
- }
- case TRANSIT_OLD_TASK_FRAGMENT_OPEN: {
- return "TRANSIT_OLD_TASK_FRAGMENT_OPEN";
- }
- case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: {
- return "TRANSIT_OLD_TASK_FRAGMENT_CLOSE";
- }
- case TRANSIT_OLD_TASK_FRAGMENT_CHANGE: {
- return "TRANSIT_OLD_TASK_FRAGMENT_CHANGE";
- }
- case TRANSIT_OLD_DREAM_ACTIVITY_OPEN: {
- return "TRANSIT_OLD_DREAM_ACTIVITY_OPEN";
- }
- case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE: {
- return "TRANSIT_OLD_DREAM_ACTIVITY_CLOSE";
- }
- default: {
- return "<UNKNOWN: " + transition + ">";
- }
- }
- }
-
- /**
- * Returns the human readable name of a window transition.
- *
- * @param transition The window transition.
- * @return The transition symbolic name.
- */
- public static String appTransitionToString(@TransitionType int transition) {
- switch (transition) {
- case TRANSIT_NONE: {
- return "TRANSIT_NONE";
- }
- case TRANSIT_OPEN: {
- return "TRANSIT_OPEN";
- }
- case TRANSIT_CLOSE: {
- return "TRANSIT_CLOSE";
- }
- case TRANSIT_TO_FRONT: {
- return "TRANSIT_TO_FRONT";
- }
- case TRANSIT_TO_BACK: {
- return "TRANSIT_TO_BACK";
- }
- case TRANSIT_RELAUNCH: {
- return "TRANSIT_RELAUNCH";
- }
- case TRANSIT_CHANGE: {
- return "TRANSIT_CHANGE";
- }
- case TRANSIT_KEYGUARD_GOING_AWAY: {
- return "TRANSIT_KEYGUARD_GOING_AWAY";
- }
- case TRANSIT_KEYGUARD_OCCLUDE: {
- return "TRANSIT_KEYGUARD_OCCLUDE";
- }
- case TRANSIT_KEYGUARD_UNOCCLUDE: {
- return "TRANSIT_KEYGUARD_UNOCCLUDE";
- }
- default: {
- return "<UNKNOWN: " + transition + ">";
- }
- }
- }
-
- private String appStateToString() {
- switch (mAppTransitionState) {
- case APP_STATE_IDLE:
- return "APP_STATE_IDLE";
- case APP_STATE_READY:
- return "APP_STATE_READY";
- case APP_STATE_RUNNING:
- return "APP_STATE_RUNNING";
- case APP_STATE_TIMEOUT:
- return "APP_STATE_TIMEOUT";
- default:
- return "unknown state=" + mAppTransitionState;
- }
- }
-
- private String transitTypeToString() {
- switch (mNextAppTransitionType) {
- case NEXT_TRANSIT_TYPE_NONE:
- return "NEXT_TRANSIT_TYPE_NONE";
- case NEXT_TRANSIT_TYPE_CUSTOM:
- return "NEXT_TRANSIT_TYPE_CUSTOM";
- case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
- return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
- case NEXT_TRANSIT_TYPE_SCALE_UP:
- return "NEXT_TRANSIT_TYPE_SCALE_UP";
- case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
- return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
- case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
- return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
- case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
- return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
- case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
- return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
- case NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:
- return "NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS";
- default:
- return "unknown type=" + mNextAppTransitionType;
- }
- }
-
- private static final ArrayList<Pair<Integer, String>> sFlagToString;
-
- static {
- sFlagToString = new ArrayList<>();
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE,
- "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE"));
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION,
- "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION"));
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER,
- "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER"));
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION,
- "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION"));
- sFlagToString.add(new Pair<>(
- TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT,
- "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_WITH_IN_WINDOW_ANIMATIONS"));
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_APP_CRASHED,
- "TRANSIT_FLAG_APP_CRASHED"));
- sFlagToString.add(new Pair<>(TRANSIT_FLAG_OPEN_BEHIND,
- "TRANSIT_FLAG_OPEN_BEHIND"));
- }
-
- /**
- * Returns the human readable names of transit flags.
- *
- * @param flags a bitmask combination of transit flags.
- * @return The combination of symbolic names.
- */
- public static String appTransitionFlagsToString(int flags) {
- String sep = "";
- StringBuilder sb = new StringBuilder();
- for (Pair<Integer, String> pair : sFlagToString) {
- if ((flags & pair.first) != 0) {
- sb.append(sep);
- sb.append(pair.second);
- sep = " | ";
- }
- }
- return sb.toString();
- }
-
- void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(APP_TRANSITION_STATE, mAppTransitionState);
- proto.write(LAST_USED_APP_TRANSITION, mLastUsedAppTransition);
- proto.end(token);
- }
-
- @Override
- public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.println(this);
- pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
- if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
- pw.print(prefix); pw.print("mNextAppTransitionType=");
- pw.println(transitTypeToString());
- }
- if (mNextAppTransitionOverrideRequested
- || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
- pw.print(prefix); pw.print("mNextAppTransitionPackage=");
- pw.println(mNextAppTransitionPackage);
- pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
- pw.print(Integer.toHexString(mNextAppTransitionEnter));
- pw.print(" mNextAppTransitionExit=0x");
- pw.println(Integer.toHexString(mNextAppTransitionExit));
- pw.print(" mNextAppTransitionBackgroundColor=0x");
- pw.println(Integer.toHexString(mNextAppTransitionBackgroundColor));
- }
- switch (mNextAppTransitionType) {
- case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
- pw.print(prefix); pw.print("mNextAppTransitionPackage=");
- pw.println(mNextAppTransitionPackage);
- pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
- pw.print(Integer.toHexString(mNextAppTransitionInPlace));
- break;
- case NEXT_TRANSIT_TYPE_SCALE_UP: {
- getDefaultNextAppTransitionStartRect(mTmpRect);
- pw.print(prefix); pw.print("mNextAppTransitionStartX=");
- pw.print(mTmpRect.left);
- pw.print(" mNextAppTransitionStartY=");
- pw.println(mTmpRect.top);
- pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
- pw.print(mTmpRect.width());
- pw.print(" mNextAppTransitionStartHeight=");
- pw.println(mTmpRect.height());
- break;
- }
- case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
- case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
- case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
- case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: {
- pw.print(prefix); pw.print("mDefaultNextAppTransitionAnimationSpec=");
- pw.println(mDefaultNextAppTransitionAnimationSpec);
- pw.print(prefix); pw.print("mNextAppTransitionAnimationsSpecs=");
- pw.println(mNextAppTransitionAnimationsSpecs);
- pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
- pw.println(mNextAppTransitionScaleUp);
- break;
- }
- }
- if (mNextAppTransitionCallback != null) {
- pw.print(prefix); pw.print("mNextAppTransitionCallback=");
- pw.println(mNextAppTransitionCallback);
- }
- if (mLastUsedAppTransition != TRANSIT_OLD_NONE) {
- pw.print(prefix); pw.print("mLastUsedAppTransition=");
- pw.println(appTransitionOldToString(mLastUsedAppTransition));
- pw.print(prefix); pw.print("mLastOpeningApp=");
- pw.println(mLastOpeningApp);
- pw.print(prefix); pw.print("mLastClosingApp=");
- pw.println(mLastClosingApp);
- pw.print(prefix); pw.print("mLastChangingApp=");
- pw.println(mLastChangingApp);
- }
- }
-
- boolean prepareAppTransition(@TransitionType int transit, @TransitionFlags int flags) {
- if (WindowManagerService.sEnableShellTransitions) {
- return false;
- }
- mNextAppTransitionRequests.add(transit);
- mNextAppTransitionFlags |= flags;
- updateBooster();
- removeAppTransitionTimeoutCallbacks();
- mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable,
- APP_TRANSITION_TIMEOUT_MS);
- return prepare();
- }
-
- /**
- * @return true if {@param transit} is representing a transition in which Keyguard is going
- * away, false otherwise
- */
- public static boolean isKeyguardGoingAwayTransitOld(int transit) {
- return transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY
- || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
- }
-
- static boolean isKeyguardOccludeTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_KEYGUARD_OCCLUDE
- || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM
- || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
- }
-
- static boolean isKeyguardTransitOld(@TransitionOldType int transit) {
- return isKeyguardGoingAwayTransitOld(transit) || isKeyguardOccludeTransitOld(transit);
- }
-
- static boolean isTaskTransitOld(@TransitionOldType int transit) {
- return isTaskOpenTransitOld(transit)
- || isTaskCloseTransitOld(transit);
- }
-
- static boolean isTaskCloseTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_TASK_CLOSE
- || transit == TRANSIT_OLD_TASK_TO_BACK;
- }
-
- private static boolean isTaskOpenTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_TASK_OPEN
- || transit == TRANSIT_OLD_TASK_OPEN_BEHIND
- || transit == TRANSIT_OLD_TASK_TO_FRONT;
- }
-
- static boolean isActivityTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_ACTIVITY_OPEN
- || transit == TRANSIT_OLD_ACTIVITY_CLOSE
- || transit == TRANSIT_OLD_ACTIVITY_RELAUNCH;
- }
-
- static boolean isTaskFragmentTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_TASK_FRAGMENT_OPEN
- || transit == TRANSIT_OLD_TASK_FRAGMENT_CLOSE
- || transit == TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
- }
-
- static boolean isChangeTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE
- || transit == TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
- }
-
- static boolean isClosingTransitOld(@TransitionOldType int transit) {
- return transit == TRANSIT_OLD_ACTIVITY_CLOSE
- || transit == TRANSIT_OLD_TASK_CLOSE
- || transit == TRANSIT_OLD_WALLPAPER_CLOSE
- || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE
- || transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE
- || transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
- }
-
- static boolean isNormalTransit(@TransitionType int transit) {
- return transit == TRANSIT_OPEN
- || transit == TRANSIT_CLOSE
- || transit == TRANSIT_TO_FRONT
- || transit == TRANSIT_TO_BACK;
- }
-
- static boolean isKeyguardTransit(@TransitionType int transit) {
- return transit == TRANSIT_KEYGUARD_GOING_AWAY
- || transit == TRANSIT_KEYGUARD_OCCLUDE
- || transit == TRANSIT_KEYGUARD_UNOCCLUDE;
- }
-
- @TransitionType int getKeyguardTransition() {
- if (mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_GOING_AWAY) != -1) {
- return TRANSIT_KEYGUARD_GOING_AWAY;
- }
- final int unoccludeIndex = mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_UNOCCLUDE);
- final int occludeIndex = mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_OCCLUDE);
- // No keyguard related transition requests.
- if (unoccludeIndex == -1 && occludeIndex == -1) {
- return TRANSIT_NONE;
- }
- // In case we unocclude Keyguard and occlude it again, meaning that we never actually
- // unoccclude/occlude Keyguard, but just run a normal transition.
- if (unoccludeIndex != -1 && unoccludeIndex < occludeIndex) {
- return TRANSIT_NONE;
- }
- return unoccludeIndex != -1 ? TRANSIT_KEYGUARD_UNOCCLUDE : TRANSIT_KEYGUARD_OCCLUDE;
- }
-
- @TransitionType int getFirstAppTransition() {
- for (int i = 0; i < mNextAppTransitionRequests.size(); ++i) {
- final @TransitionType int transit = mNextAppTransitionRequests.get(i);
- if (transit != TRANSIT_NONE && !isKeyguardTransit(transit)) {
- return transit;
- }
- }
- return TRANSIT_NONE;
- }
-
- boolean containsTransitRequest(@TransitionType int transit) {
- return mNextAppTransitionRequests.contains(transit);
- }
-
- private void handleAppTransitionTimeout() {
- }
-
- private static void doAnimationCallback(@NonNull IRemoteCallback callback) {
- try {
- ((IRemoteCallback) callback).sendResult(null);
- } catch (RemoteException e) {
- }
- }
-
- private void setAppTransitionFinishedCallbackIfNeeded(Animation anim) {
- final IRemoteCallback callback = mAnimationFinishedCallback;
- if (callback != null && anim != null) {
- anim.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) { }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- mHandler.sendMessage(PooledLambda.obtainMessage(
- AppTransition::doAnimationCallback, callback));
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) { }
- });
- }
- }
-
- void removeAppTransitionTimeoutCallbacks() {
- mHandler.removeCallbacks(mHandleAppTransitionTimeoutRunnable);
- }
-}
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index e9d9ace825c0..e9b7649e8cbd 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -691,8 +691,8 @@ class BackNavigationController {
return false;
}
if (window.mAttrs.windowAnimations != 0) {
- final TransitionAnimation transitionAnimation = window.getDisplayContent()
- .mAppTransition.mTransitionAnimation;
+ final TransitionAnimation transitionAnimation = window.mDisplayContent
+ .mTransitionAnimation;
final int attr = com.android.internal.R.styleable
.WindowAnimation_activityCloseExitAnimation;
final int appResId = transitionAnimation.getAnimationResId(
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 36686fc086f1..2287a687700c 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -288,9 +288,10 @@ public class BackgroundActivityStartController {
}
private boolean isHomeApp(int uid, @Nullable String packageName) {
- if (getService().mHomeProcess != null) {
- // Fast check
- return uid == getService().mHomeProcess.mUid;
+ WindowProcessController homeProcess = getService().mHomeProcess;
+ if (homeProcess != null && (homeProcess.mUid != SYSTEM_UID || packageName == null)) {
+ // Fast check (skip if sharing system UID and we have a package name)
+ return uid == homeProcess.mUid;
}
if (packageName == null) {
return false;
diff --git a/services/core/java/com/android/server/wm/BaseAppSnapshotPersister.java b/services/core/java/com/android/server/wm/BaseAppSnapshotPersister.java
index 5db02dff8351..aaa5a0074506 100644
--- a/services/core/java/com/android/server/wm/BaseAppSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/BaseAppSnapshotPersister.java
@@ -16,10 +16,20 @@
package com.android.server.wm;
+import static com.android.server.wm.AbsAppSnapshotController.TAG;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.window.TaskSnapshot;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
import java.io.File;
+import java.util.UUID;
class BaseAppSnapshotPersister {
static final String LOW_RES_FILE_POSTFIX = "_reduced";
@@ -29,6 +39,7 @@ class BaseAppSnapshotPersister {
// Shared with SnapshotPersistQueue
protected final Object mLock;
protected final SnapshotPersistQueue mSnapshotPersistQueue;
+ @VisibleForTesting
protected final PersistInfoProvider mPersistInfoProvider;
BaseAppSnapshotPersister(SnapshotPersistQueue persistQueue,
@@ -79,6 +90,8 @@ class BaseAppSnapshotPersister {
private final boolean mEnableLowResSnapshots;
private final float mLowResScaleFactor;
private final boolean mUse16BitFormat;
+ private final SparseBooleanArray mInitializedUsers = new SparseBooleanArray();
+ private final SparseArray<File> mScrambleDirectories = new SparseArray<>();
PersistInfoProvider(DirectoryResolver directoryResolver, String dirName,
boolean enableLowResSnapshots, float lowResScaleFactor, boolean use16BitFormat) {
@@ -91,9 +104,80 @@ class BaseAppSnapshotPersister {
@NonNull
File getDirectory(int userId) {
+ if (Flags.scrambleSnapshotFileName()) {
+ final File directory = getOrInitScrambleDirectory(userId);
+ if (directory != null) {
+ return directory;
+ }
+ }
+ return getBaseDirectory(userId);
+ }
+
+ @NonNull
+ private File getBaseDirectory(int userId) {
return new File(mDirectoryResolver.getSystemDirectoryForUser(userId), mDirName);
}
+ @Nullable
+ private File getOrInitScrambleDirectory(int userId) {
+ synchronized (mScrambleDirectories) {
+ if (mInitializedUsers.get(userId)) {
+ return mScrambleDirectories.get(userId);
+ }
+ mInitializedUsers.put(userId, true);
+ final File scrambledDirectory = getScrambleDirectory(userId);
+ final File baseDir = getBaseDirectory(userId);
+ String newName = null;
+ // If directory exists, rename
+ if (scrambledDirectory.exists()) {
+ newName = UUID.randomUUID().toString();
+ final File scrambleTo = new File(baseDir, newName);
+ if (!scrambledDirectory.renameTo(scrambleTo)) {
+ Slog.w(TAG, "SnapshotPersister rename scramble folder fail.");
+ return null;
+ }
+ } else {
+ // If directory not exists, mkDir.
+ if (!baseDir.exists() && !baseDir.mkdir()) {
+ Slog.w(TAG, "SnapshotPersister make base folder fail.");
+ return null;
+ }
+ if (!scrambledDirectory.mkdir()) {
+ Slog.e(TAG, "SnapshotPersister make scramble folder fail");
+ return null;
+ }
+ // Move any existing files to this folder.
+ final String[] files = baseDir.list();
+ if (files != null) {
+ for (String file : files) {
+ final File original = new File(baseDir, file);
+ if (original.isDirectory()) {
+ newName = file;
+ } else {
+ File to = new File(scrambledDirectory, file);
+ original.renameTo(to);
+ }
+ }
+ }
+ }
+ final File newFolder = new File(baseDir, newName);
+ mScrambleDirectories.put(userId, newFolder);
+ return newFolder;
+ }
+ }
+
+ @NonNull
+ private File getScrambleDirectory(int userId) {
+ final File dir = getBaseDirectory(userId);
+ final String[] directories = dir.list(
+ (current, name) -> new File(current, name).isDirectory());
+ if (directories != null && directories.length > 0) {
+ return new File(dir, directories[0]);
+ } else {
+ return new File(dir, UUID.randomUUID().toString());
+ }
+ }
+
/**
* Return if task snapshots are stored in 16 bit pixel format.
*
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index eb6b14545cb8..353ccd5836c8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -99,7 +99,6 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_SCREEN_ON;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS;
import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
-import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -247,6 +246,7 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.policy.TransitionAnimation;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -364,7 +364,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private boolean mTmpInitial;
private int mMaxUiWidth = 0;
- final AppTransition mAppTransition;
+ // TODO(b/400335290): extract the needed methods and remove this field.
+ final TransitionAnimation mTransitionAnimation;
final UnknownAppVisibilityController mUnknownAppVisibilityController;
@@ -1179,7 +1180,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mHoldScreenWakeLock.setReferenceCounted(false);
mFixedRotationTransitionListener = new FixedRotationTransitionListener(mDisplayId);
- mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
+ mTransitionAnimation = new TransitionAnimation(mWmService.mContext, false /* debug */, TAG);
mTransitionController.registerLegacyListener(mFixedRotationTransitionListener);
mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
mRemoteDisplayChangeController = new RemoteDisplayChangeController(this);
@@ -3257,16 +3258,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
void onDisplayInfoChangeApplied() {
- if (!enableDisplayContentModeManagement()) {
+ if (!DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
Slog.e(TAG, "ShouldShowSystemDecors shouldn't be updated when the flag is off.");
}
- final boolean shouldShowContent;
if (!allowContentModeSwitch()) {
return;
}
- shouldShowContent = mDisplay.canHostTasks();
+ final boolean shouldShowContent = mDisplay.canHostTasks();
if (shouldShowContent == mWmService.mDisplayWindowSettings
.shouldShowSystemDecorsLocked(this)) {
return;
@@ -3276,9 +3276,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (!shouldShowContent) {
clearAllTasksOnDisplay(null /* clearTasksCallback */, false /* isRemovingDisplay */);
}
+
+ // If the display is allowed to show content, then it belongs to the display topology;
+ // vice versa.
+ mWmService.mDisplayManagerInternal.onDisplayBelongToTopologyChanged(mDisplayId,
+ /* inTopology= */ shouldShowContent);
}
/**
+ * Whether the display is allowed to switch the content mode between extended and mirroring.
+ * If the content mode is extended, the display will start home activity and show system
+ * decorations, such as wallpapaer, status bar and navigation bar.
+ * If the content mode is mirroring, the display will not show home activity or system
+ * decorations.
+ * The content mode is switched when {@link Display#canHostTasks()} changes.
+ *
* Note that we only allow displays that are able to show system decorations to use the content
* mode switch; however, not all displays that are able to show system decorations are allowed
* to use the content mode switch.
@@ -3294,6 +3306,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return false;
}
+ if (shouldNeverShowSystemDecorations()) {
+ return false;
+ }
+
// TODO(b/391965805): Remove this after introducing FLAG_ALLOW_CONTENT_MODE_SWITCH.
if ((mDisplay.getFlags() & Display.FLAG_REAR) != 0) {
return false;
@@ -5658,16 +5674,23 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT;
}
- /**
- * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
- */
- boolean isSystemDecorationsSupported() {
+ private boolean shouldNeverShowSystemDecorations() {
if (mDisplayId == mWmService.mVr2dDisplayId) {
// VR virtual display will be used to run and render 2D app within a VR experience.
- return false;
+ return true;
}
if (!isTrusted()) {
// Do not show system decorations on untrusted virtual display.
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ boolean isSystemDecorationsSupported() {
+ if (shouldNeverShowSystemDecorations()) {
return false;
}
if (mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index ec5b503fbb9b..313b77ed4b20 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -67,7 +67,6 @@ import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_SCREEN_ON;
-import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -107,6 +106,7 @@ import android.view.InsetsFlags;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
import android.view.InsetsState;
+import android.view.PrivacyIndicatorBounds;
import android.view.Surface;
import android.view.View;
import android.view.ViewDebug;
@@ -119,6 +119,7 @@ import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.window.ClientWindowFrames;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import com.android.internal.R;
@@ -747,7 +748,7 @@ public class DisplayPolicy {
}
void updateHasNavigationBarIfNeeded() {
- if (!enableDisplayContentModeManagement()) {
+ if (!DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
Slog.e(TAG, "mHasNavigationBar shouldn't be updated when the flag is off.");
}
@@ -1875,7 +1876,7 @@ public class DisplayPolicy {
}
void notifyDisplayAddSystemDecorations() {
- if (enableDisplayContentModeManagement()) {
+ if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
final int displayId = getDisplayId();
final boolean isSystemDecorationsSupported =
mDisplayContent.isSystemDecorationsSupported();
@@ -2121,6 +2122,8 @@ public class DisplayPolicy {
}
private static class Cache {
+ static final int TYPE_REGULAR_BARS = WindowInsets.Type.statusBars()
+ | WindowInsets.Type.navigationBars();
/**
* If {@link #mPreserveId} is this value, it is in the middle of updating display
* configuration before a transition is started. Then the active cache should be used.
@@ -2130,6 +2133,14 @@ public class DisplayPolicy {
int mPreserveId;
boolean mActive;
+ /**
+ * When display switches, mRegularBarsInsets will assign to mPreservedInsets, and the
+ * insets sources of previous device state will copy to mRegularBarsInsets.
+ */
+ ArrayList<InsetsSource> mPreservedInsets;
+ ArrayList<InsetsSource> mRegularBarsInsets;
+ PrivacyIndicatorBounds mPrivacyIndicatorBounds;
+
Cache(DisplayContent dc) {
mDecorInsets = new DecorInsets(dc);
}
@@ -2138,6 +2149,17 @@ public class DisplayPolicy {
return mPreserveId == ID_UPDATING_CONFIG || mDecorInsets.mDisplayContent
.mTransitionController.inTransition(mPreserveId);
}
+
+ static ArrayList<InsetsSource> copyRegularBarInsets(InsetsState srcState) {
+ final ArrayList<InsetsSource> state = new ArrayList<>();
+ for (int i = srcState.sourceSize() - 1; i >= 0; i--) {
+ final InsetsSource source = srcState.sourceAt(i);
+ if ((source.getType() & TYPE_REGULAR_BARS) != 0) {
+ state.add(new InsetsSource(source));
+ }
+ }
+ return state;
+ }
}
}
@@ -2213,24 +2235,60 @@ public class DisplayPolicy {
@VisibleForTesting
void updateCachedDecorInsets() {
DecorInsets prevCache = null;
+ PrivacyIndicatorBounds privacyIndicatorBounds = null;
if (mCachedDecorInsets == null) {
mCachedDecorInsets = new DecorInsets.Cache(mDisplayContent);
} else {
prevCache = new DecorInsets(mDisplayContent);
prevCache.setTo(mCachedDecorInsets.mDecorInsets);
+ privacyIndicatorBounds = mCachedDecorInsets.mPrivacyIndicatorBounds;
+ mCachedDecorInsets.mPreservedInsets = mCachedDecorInsets.mRegularBarsInsets;
}
// Set a special id to preserve it before a real id is available from transition.
mCachedDecorInsets.mPreserveId = DecorInsets.Cache.ID_UPDATING_CONFIG;
// Cache the current insets.
mCachedDecorInsets.mDecorInsets.setTo(mDecorInsets);
+ if (com.android.window.flags.Flags.useCachedInsetsForDisplaySwitch()) {
+ mCachedDecorInsets.mRegularBarsInsets = DecorInsets.Cache.copyRegularBarInsets(
+ mDisplayContent.mDisplayFrames.mInsetsState);
+ mCachedDecorInsets.mPrivacyIndicatorBounds =
+ mDisplayContent.mCurrentPrivacyIndicatorBounds;
+ } else {
+ mCachedDecorInsets.mRegularBarsInsets = null;
+ mCachedDecorInsets.mPrivacyIndicatorBounds = null;
+ }
// Switch current to previous cache.
if (prevCache != null) {
mDecorInsets.setTo(prevCache);
+ if (privacyIndicatorBounds != null) {
+ mDisplayContent.mCurrentPrivacyIndicatorBounds = privacyIndicatorBounds;
+ }
mCachedDecorInsets.mActive = true;
}
}
/**
+ * This returns a new InsetsState with replacing the insets in target device state when the
+ * display is switching (e.g. fold/unfold). Otherwise, it returns the original state. This is
+ * to avoid dispatching old insets source before the insets providers update new insets.
+ */
+ InsetsState replaceInsetsSourcesIfNeeded(InsetsState originalState, boolean copyState) {
+ if (mCachedDecorInsets == null || mCachedDecorInsets.mPreservedInsets == null
+ || !shouldKeepCurrentDecorInsets()) {
+ return originalState;
+ }
+ final ArrayList<InsetsSource> preservedSources = mCachedDecorInsets.mPreservedInsets;
+ final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
+ for (int i = preservedSources.size() - 1; i >= 0; i--) {
+ final InsetsSource cacheSource = preservedSources.get(i);
+ if (state.peekSource(cacheSource.getId()) != null) {
+ state.addSource(new InsetsSource(cacheSource));
+ }
+ }
+ return state;
+ }
+
+ /**
* Called after the display configuration is updated according to the physical change. Suppose
* there should be a display change transition, so associate the cached decor insets with the
* transition to limit the lifetime of using the cache.
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index fa7a99d55896..d90fff229cd9 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -40,14 +40,14 @@ class DisplayWindowListenerController {
}
int[] registerListener(IDisplayWindowListener listener) {
+ mDisplayListeners.register(listener);
+ final IntArray displayIds = new IntArray();
synchronized (mService.mGlobalLock) {
- mDisplayListeners.register(listener);
- final IntArray displayIds = new IntArray();
mService.mAtmService.mRootWindowContainer.forAllDisplays((displayContent) -> {
displayIds.add(displayContent.mDisplayId);
});
- return displayIds.toArray();
}
+ return displayIds.toArray();
}
void unregisterListener(IDisplayWindowListener listener) {
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index c6892e941fc6..56579206566f 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -23,7 +23,6 @@ import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
-import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
@@ -37,6 +36,7 @@ import android.view.IWindowManager;
import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
+import android.window.DesktopExperienceFlags;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.DisplayContent.ForceScalingMode;
@@ -240,6 +240,11 @@ class DisplayWindowSettings {
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
+ /**
+ * Returns {@code true} if either the display is the default display, or the display is allowed
+ * to dynamically add/remove system decorations and the system decorations should be shown on it
+ * currently.
+ */
boolean shouldShowSystemDecorsLocked(@NonNull DisplayContent dc) {
if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
// Default display should show system decors.
@@ -255,7 +260,7 @@ class DisplayWindowSettings {
final boolean changed = (shouldShow != shouldShowSystemDecorsLocked(dc));
setShouldShowSystemDecorsInternalLocked(dc, shouldShow);
- if (enableDisplayContentModeManagement()) {
+ if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
if (dc.isDefaultDisplay || dc.isPrivate() || !changed) {
return;
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 28722141dcd3..06754c4517ab 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -229,6 +229,7 @@ class InsetsPolicy {
state = originalState;
}
state = adjustVisibilityForIme(target, state, state == originalState);
+ state = mPolicy.replaceInsetsSourcesIfNeeded(state, state == originalState);
return adjustInsetsForRoundedCorners(target.mToken, state, state == originalState);
}
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 29c0c7b2035e..3a4d2ca8b9bd 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -54,7 +54,6 @@ public class Letterbox {
private final Supplier<SurfaceControl.Builder> mSurfaceControlFactory;
private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
- private final Supplier<SurfaceControl> mParentSurfaceSupplier;
private final Rect mOuter = new Rect();
private final Rect mInner = new Rect();
@@ -83,13 +82,11 @@ public class Letterbox {
public Letterbox(Supplier<SurfaceControl.Builder> surfaceControlFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
@NonNull AppCompatReachabilityPolicy appCompatReachabilityPolicy,
- @NonNull AppCompatLetterboxOverrides appCompatLetterboxOverrides,
- Supplier<SurfaceControl> parentSurface) {
+ @NonNull AppCompatLetterboxOverrides appCompatLetterboxOverrides) {
mSurfaceControlFactory = surfaceControlFactory;
mTransactionFactory = transactionFactory;
mAppCompatReachabilityPolicy = appCompatReachabilityPolicy;
mAppCompatLetterboxOverrides = appCompatLetterboxOverrides;
- mParentSurfaceSupplier = parentSurface;
}
/**
@@ -343,7 +340,6 @@ public class Letterbox {
private SurfaceControl mInputSurface;
private Color mColor;
private boolean mHasWallpaperBackground;
- private SurfaceControl mParentSurface;
private final Rect mSurfaceFrameRelative = new Rect();
private final Rect mLayoutFrameGlobal = new Rect();
@@ -437,9 +433,8 @@ public class Letterbox {
}
mColor = mAppCompatLetterboxOverrides.getLetterboxBackgroundColor();
- mParentSurface = mParentSurfaceSupplier.get();
t.setColor(mSurface, getRgbColorArray());
- setPositionAndReparent(t, mSurface);
+ setPositionAndCrop(t, mSurface);
mHasWallpaperBackground = mAppCompatLetterboxOverrides
.hasWallpaperBackgroundForLetterbox();
@@ -448,7 +443,7 @@ public class Letterbox {
t.show(mSurface);
if (mInputSurface != null) {
- setPositionAndReparent(inputT, mInputSurface);
+ setPositionAndCrop(inputT, mInputSurface);
inputT.setTrustedOverlay(mInputSurface, true);
inputT.show(mInputSurface);
}
@@ -470,12 +465,11 @@ public class Letterbox {
}
}
- private void setPositionAndReparent(@NonNull SurfaceControl.Transaction t,
+ private void setPositionAndCrop(@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl surface) {
t.setPosition(surface, mSurfaceFrameRelative.left, mSurfaceFrameRelative.top);
t.setWindowCrop(surface, mSurfaceFrameRelative.width(),
mSurfaceFrameRelative.height());
- t.reparent(surface, mParentSurface);
}
private void updateAlphaAndBlur(SurfaceControl.Transaction t) {
@@ -511,14 +505,13 @@ public class Letterbox {
public boolean needsApplySurfaceChanges() {
return !mSurfaceFrameRelative.equals(mLayoutFrameRelative)
- // If mSurfaceFrameRelative is empty then mHasWallpaperBackground, mColor,
- // and mParentSurface may never be updated in applySurfaceChanges but this
- // doesn't mean that update is needed.
+ // If mSurfaceFrameRelative is empty, then mHasWallpaperBackground and mColor
+ // may never be updated in applySurfaceChanges but this doesn't mean that
+ // update is needed.
|| !mSurfaceFrameRelative.isEmpty()
&& (mAppCompatLetterboxOverrides.hasWallpaperBackgroundForLetterbox()
!= mHasWallpaperBackground
- || !mAppCompatLetterboxOverrides.getLetterboxBackgroundColor().equals(mColor)
- || mParentSurfaceSupplier.get() != mParentSurface);
+ || !mAppCompatLetterboxOverrides.getLetterboxBackgroundColor().equals(mColor));
}
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index e864ecf60770..cf201c9f34f0 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -36,6 +36,7 @@ import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_WAKE;
+import static android.window.DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_FOCUS_LIGHT;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_KEEP_SCREEN_ON;
@@ -45,7 +46,6 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_STATES;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_SURFACE_ALLOC;
-import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1371,7 +1371,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// When display content mode management flag is enabled, the task display area is marked as
// removed when switching from extended display to mirroring display. We need to restart the
// task display area before starting the home.
- if (enableDisplayContentModeManagement() && taskDisplayArea.shouldKeepNoTask()) {
+ if (ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()
+ && taskDisplayArea.shouldKeepNoTask()) {
taskDisplayArea.setShouldKeepNoTask(false);
}
@@ -2771,10 +2772,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return;
}
- if (enableDisplayContentModeManagement() && display.allowContentModeSwitch()) {
- mWindowManager.mDisplayWindowSettings
- .setShouldShowSystemDecorsInternalLocked(display,
- display.mDisplay.canHostTasks());
+ if (ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
+ if (display.allowContentModeSwitch()) {
+ mWindowManager.mDisplayWindowSettings
+ .setShouldShowSystemDecorsInternalLocked(display,
+ display.mDisplay.canHostTasks());
+ }
+
+ final boolean inTopology = mWindowManager.mDisplayWindowSettings
+ .shouldShowSystemDecorsLocked(display);
+ mWmService.mDisplayManagerInternal.onDisplayBelongToTopologyChanged(displayId,
+ inTopology);
}
startSystemDecorations(display, "displayAdded");
@@ -2823,7 +2831,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
displayContent.requestDisplayUpdate(
() -> {
clearDisplayInfoCaches(displayId);
- if (enableDisplayContentModeManagement()) {
+ if (ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
displayContent.onDisplayInfoChangeApplied();
}
});
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 22f0278b3a30..d16c301cec40 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4497,7 +4497,7 @@ class Task extends TaskFragment {
}
void onPictureInPictureParamsChanged() {
- if (inPinnedWindowingMode() || Flags.enableDesktopWindowingPip()) {
+ if (inPinnedWindowingMode() || DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) {
dispatchTaskInfoChangedIfNeeded(true /* force */);
}
}
diff --git a/services/core/java/com/android/server/wm/ViewServer.java b/services/core/java/com/android/server/wm/ViewServer.java
index ecf5652a1e69..971e6f95d6bd 100644
--- a/services/core/java/com/android/server/wm/ViewServer.java
+++ b/services/core/java/com/android/server/wm/ViewServer.java
@@ -19,7 +19,10 @@ package com.android.server.wm;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerInternal.WindowFocusChangeListener;
+import static com.android.server.wm.WindowManagerService.WindowChangeListener;
+import android.os.IBinder;
import android.util.Slog;
import java.net.ServerSocket;
@@ -206,7 +209,7 @@ class ViewServer implements Runnable {
return result;
}
- class ViewServerWorker implements Runnable, WindowManagerService.WindowChangeListener {
+ class ViewServerWorker implements Runnable, WindowChangeListener, WindowFocusChangeListener {
private Socket mClient;
private boolean mNeedWindowListUpdate;
private boolean mNeedFocusedWindowUpdate;
@@ -284,7 +287,7 @@ class ViewServer implements Runnable {
}
}
- public void focusChanged() {
+ public void focusChanged(IBinder focusedWindowToken) {
synchronized(this) {
mNeedFocusedWindowUpdate = true;
notifyAll();
@@ -293,6 +296,7 @@ class ViewServer implements Runnable {
private boolean windowManagerAutolistLoop() {
mWindowManager.addWindowChangeListener(this);
+ mWindowManager.addWindowFocusChangeListener(this);
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(mClient.getOutputStream()));
@@ -332,6 +336,7 @@ class ViewServer implements Runnable {
}
}
mWindowManager.removeWindowChangeListener(this);
+ mWindowManager.removeWindowFocusChangeListener(this);
}
return true;
}
diff --git a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java b/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
deleted file mode 100644
index d3530c50348a..000000000000
--- a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static com.android.server.wm.AnimationAdapter.STATUS_BAR_TRANSITION_DURATION;
-import static com.android.server.wm.AnimationSpecProto.WINDOW;
-import static com.android.server.wm.WindowAnimationSpecProto.ANIMATION;
-
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.util.proto.ProtoOutputStream;
-import android.view.DisplayInfo;
-import android.view.SurfaceControl;
-import android.view.SurfaceControl.Transaction;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.ClipRectAnimation;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.Transformation;
-import android.view.animation.TranslateAnimation;
-
-import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
-
-import java.io.PrintWriter;
-
-/**
- * Animation spec for changing window animations.
- */
-public class WindowChangeAnimationSpec implements AnimationSpec {
-
- private final ThreadLocal<TmpValues> mThreadLocalTmps = ThreadLocal.withInitial(TmpValues::new);
- private final boolean mIsAppAnimation;
- private final Rect mStartBounds;
- private final Rect mEndBounds;
- private final Rect mTmpRect = new Rect();
-
- private Animation mAnimation;
- private final boolean mIsThumbnail;
-
- static final int ANIMATION_DURATION = AppTransition.DEFAULT_APP_TRANSITION_DURATION;
-
- public WindowChangeAnimationSpec(Rect startBounds, Rect endBounds, DisplayInfo displayInfo,
- float durationScale, boolean isAppAnimation, boolean isThumbnail) {
- mStartBounds = new Rect(startBounds);
- mEndBounds = new Rect(endBounds);
- mIsAppAnimation = isAppAnimation;
- mIsThumbnail = isThumbnail;
- createBoundsInterpolator((int) (ANIMATION_DURATION * durationScale), displayInfo);
- }
-
- @Override
- public boolean getShowWallpaper() {
- return false;
- }
-
- @Override
- public long getDuration() {
- return mAnimation.getDuration();
- }
-
- /**
- * This animator behaves slightly differently depending on whether the window is growing
- * or shrinking:
- * If growing, it will do a clip-reveal after quicker fade-out/scale of the smaller (old)
- * snapshot.
- * If shrinking, it will do an opposite clip-reveal on the old snapshot followed by a quicker
- * fade-out of the bigger (old) snapshot while simultaneously shrinking the new window into
- * place.
- * @param duration
- * @param displayInfo
- */
- private void createBoundsInterpolator(long duration, DisplayInfo displayInfo) {
- boolean growing = mEndBounds.width() - mStartBounds.width()
- + mEndBounds.height() - mStartBounds.height() >= 0;
- float scalePart = 0.7f;
- long scalePeriod = (long) (duration * scalePart);
- float startScaleX = scalePart * ((float) mStartBounds.width()) / mEndBounds.width()
- + (1.f - scalePart);
- float startScaleY = scalePart * ((float) mStartBounds.height()) / mEndBounds.height()
- + (1.f - scalePart);
- if (mIsThumbnail) {
- AnimationSet animSet = new AnimationSet(true);
- Animation anim = new AlphaAnimation(1.f, 0.f);
- anim.setDuration(scalePeriod);
- if (!growing) {
- anim.setStartOffset(duration - scalePeriod);
- }
- animSet.addAnimation(anim);
- float endScaleX = 1.f / startScaleX;
- float endScaleY = 1.f / startScaleY;
- anim = new ScaleAnimation(endScaleX, endScaleX, endScaleY, endScaleY);
- anim.setDuration(duration);
- animSet.addAnimation(anim);
- mAnimation = animSet;
- mAnimation.initialize(mStartBounds.width(), mStartBounds.height(),
- mEndBounds.width(), mEndBounds.height());
- } else {
- AnimationSet animSet = new AnimationSet(true);
- final Animation scaleAnim = new ScaleAnimation(startScaleX, 1, startScaleY, 1);
- scaleAnim.setDuration(scalePeriod);
- if (!growing) {
- scaleAnim.setStartOffset(duration - scalePeriod);
- }
- animSet.addAnimation(scaleAnim);
- final Animation translateAnim = new TranslateAnimation(mStartBounds.left,
- mEndBounds.left, mStartBounds.top, mEndBounds.top);
- translateAnim.setDuration(duration);
- animSet.addAnimation(translateAnim);
- Rect startClip = new Rect(mStartBounds);
- Rect endClip = new Rect(mEndBounds);
- startClip.offsetTo(0, 0);
- endClip.offsetTo(0, 0);
- final Animation clipAnim = new ClipRectAnimation(startClip, endClip);
- clipAnim.setDuration(duration);
- animSet.addAnimation(clipAnim);
- mAnimation = animSet;
- mAnimation.initialize(mStartBounds.width(), mStartBounds.height(),
- displayInfo.appWidth, displayInfo.appHeight);
- }
- }
-
- @Override
- public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
- final TmpValues tmp = mThreadLocalTmps.get();
- if (mIsThumbnail) {
- mAnimation.getTransformation(currentPlayTime, tmp.mTransformation);
- t.setMatrix(leash, tmp.mTransformation.getMatrix(), tmp.mFloats);
- t.setAlpha(leash, tmp.mTransformation.getAlpha());
- } else {
- mAnimation.getTransformation(currentPlayTime, tmp.mTransformation);
- final Matrix matrix = tmp.mTransformation.getMatrix();
- t.setMatrix(leash, matrix, tmp.mFloats);
-
- // The following applies an inverse scale to the clip-rect so that it crops "after" the
- // scale instead of before.
- tmp.mVecs[1] = tmp.mVecs[2] = 0;
- tmp.mVecs[0] = tmp.mVecs[3] = 1;
- matrix.mapVectors(tmp.mVecs);
- tmp.mVecs[0] = 1.f / tmp.mVecs[0];
- tmp.mVecs[3] = 1.f / tmp.mVecs[3];
- final Rect clipRect = tmp.mTransformation.getClipRect();
- mTmpRect.left = (int) (clipRect.left * tmp.mVecs[0] + 0.5f);
- mTmpRect.right = (int) (clipRect.right * tmp.mVecs[0] + 0.5f);
- mTmpRect.top = (int) (clipRect.top * tmp.mVecs[3] + 0.5f);
- mTmpRect.bottom = (int) (clipRect.bottom * tmp.mVecs[3] + 0.5f);
- t.setWindowCrop(leash, mTmpRect);
- }
- }
-
- @Override
- public long calculateStatusBarTransitionStartTime() {
- long uptime = SystemClock.uptimeMillis();
- return Math.max(uptime, uptime + ((long) (((float) mAnimation.getDuration()) * 0.99f))
- - STATUS_BAR_TRANSITION_DURATION);
- }
-
- @Override
- public boolean canSkipFirstFrame() {
- return false;
- }
-
- @Override
- public boolean needsEarlyWakeup() {
- return mIsAppAnimation;
- }
-
- @Override
- public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.println(mAnimation.getDuration());
- }
-
- @Override
- public void dumpDebugInner(ProtoOutputStream proto) {
- final long token = proto.start(WINDOW);
- proto.write(ANIMATION, mAnimation.toString());
- proto.end(token);
- }
-
- private static class TmpValues {
- final Transformation mTransformation = new Transformation();
- final float[] mFloats = new float[9];
- final float[] mVecs = new float[4];
- }
-}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index e3746f18dca0..466ed7863c84 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -97,7 +97,6 @@ import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import com.android.server.wm.utils.AlwaysTruePredicate;
-import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -2630,7 +2629,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
if (!mTransitionController.canAssignLayers(this)) return;
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
if (mSurfaceControl != null && changed) {
- if (Flags.useSelfSyncTransactionForLayer() && mSyncState != SYNC_STATE_NONE) {
+ if (mSyncState != SYNC_STATE_NONE) {
// When this container needs to be synced, assign layer with its own sync
// transaction to avoid out of ordering when merge.
// Still use the passed-in transaction for non-sync case, such as building finish
@@ -2647,7 +2646,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
boolean forceUpdate) {
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != relativeTo;
if (mSurfaceControl != null && (changed || forceUpdate)) {
- if (Flags.useSelfSyncTransactionForLayer() && mSyncState != SYNC_STATE_NONE) {
+ if (mSyncState != SYNC_STATE_NONE) {
// When this container needs to be synced, assign layer with its own sync
// transaction to avoid out of ordering when merge.
// Still use the passed-in transaction for non-sync case, such as building finish
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 6e224f07fcdc..4b5a3a031931 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -152,6 +152,30 @@ public abstract class WindowManagerInternal {
}
}
+ /** Interface for clients to receive callbacks related to window change. */
+ public interface WindowFocusChangeListener {
+ /**
+ * Notify on focus changed.
+ *
+ * @param focusedWindowToken the token of the newly focused window.
+ */
+ void focusChanged(@NonNull IBinder focusedWindowToken);
+ }
+
+ /**
+ * Registers a listener to be notified about window focus changes.
+ *
+ * @param listener the {@link WindowFocusChangeListener} to register.
+ */
+ public abstract void registerWindowFocusChangeListener(WindowFocusChangeListener listener);
+
+ /**
+ * Unregisters a listener that was registered via {@link #registerWindowFocusChangeListener}.
+ *
+ * @param listener the {@link WindowFocusChangeListener} to unregister.
+ */
+ public abstract void unregisterWindowFocusChangeListener(WindowFocusChangeListener listener);
+
/**
* Interface to receive a callback when the windows reported for
* accessibility changed.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 54f960973eff..9fc0339c52a2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -145,6 +145,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSA
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerInternal.OnWindowRemovedListener;
+import static com.android.server.wm.WindowManagerInternal.WindowFocusChangeListener;
import static com.android.server.wm.WindowManagerServiceDumpProto.BACK_NAVIGATION;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
@@ -1078,14 +1079,12 @@ public class WindowManagerService extends IWindowManager.Stub
private ViewServer mViewServer;
final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
+ final ArrayList<WindowFocusChangeListener> mWindowFocusChangeListeners = new ArrayList<>();
boolean mWindowsChanged = false;
- public interface WindowChangeListener {
+ interface WindowChangeListener {
/** Notify on windows changed */
void windowsChanged();
-
- /** Notify on focus changed */
- void focusChanged();
}
final HighRefreshRateDenylist mHighRefreshRateDenylist;
@@ -5306,18 +5305,30 @@ public class WindowManagerService extends IWindowManager.Stub
return success;
}
- public void addWindowChangeListener(WindowChangeListener listener) {
+ void addWindowChangeListener(WindowChangeListener listener) {
synchronized (mGlobalLock) {
mWindowChangeListeners.add(listener);
}
}
- public void removeWindowChangeListener(WindowChangeListener listener) {
+ void removeWindowChangeListener(WindowChangeListener listener) {
synchronized (mGlobalLock) {
mWindowChangeListeners.remove(listener);
}
}
+ void addWindowFocusChangeListener(WindowFocusChangeListener listener) {
+ synchronized (mGlobalLock) {
+ mWindowFocusChangeListeners.add(listener);
+ }
+ }
+
+ void removeWindowFocusChangeListener(WindowFocusChangeListener listener) {
+ synchronized (mGlobalLock) {
+ mWindowFocusChangeListeners.remove(listener);
+ }
+ }
+
private void notifyWindowRemovedListeners(IBinder client) {
OnWindowRemovedListener[] windowRemovedListeners;
synchronized (mGlobalLock) {
@@ -5350,18 +5361,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private void notifyFocusChanged() {
- WindowChangeListener[] windowChangeListeners;
+ private void notifyFocusChanged(IBinder focusedWindowToken) {
+ WindowFocusChangeListener[] windowFocusChangeListeners;
synchronized (mGlobalLock) {
- if(mWindowChangeListeners.isEmpty()) {
+ if(mWindowFocusChangeListeners.isEmpty()) {
return;
}
- windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
- windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
+ windowFocusChangeListeners =
+ new WindowFocusChangeListener[mWindowFocusChangeListeners.size()];
+ mWindowFocusChangeListeners.toArray(windowFocusChangeListeners);
}
- int N = windowChangeListeners.length;
+ int N = windowFocusChangeListeners.length;
for(int i = 0; i < N; i++) {
- windowChangeListeners[i].focusChanged();
+ windowFocusChangeListeners[i].focusChanged(focusedWindowToken);
}
}
@@ -5636,7 +5648,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (newFocusedWindow != null && newFocusedWindow.mInputChannelToken == newToken) {
mAnrController.onFocusChanged(newFocusedWindow);
newFocusedWindow.reportFocusChangedSerialized(true);
- notifyFocusChanged();
+ notifyFocusChanged(newTarget.getWindowToken());
}
WindowState lastFocusedWindow = lastTarget != null ? lastTarget.getWindowState() : null;
@@ -8650,6 +8662,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void registerWindowFocusChangeListener(WindowFocusChangeListener listener) {
+ WindowManagerService.this.addWindowFocusChangeListener(listener);
+ }
+
+ @Override
+ public void unregisterWindowFocusChangeListener(WindowFocusChangeListener listener) {
+ WindowManagerService.this.removeWindowFocusChangeListener(listener);
+ }
+
+ @Override
public void registerOnWindowRemovedListener(OnWindowRemovedListener listener) {
synchronized (mGlobalLock) {
mOnWindowRemovedListeners.add(listener);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3b7d31274326..1022d18ac0e9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5447,7 +5447,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
void assignLayer(Transaction t, int layer) {
if (mStartingData != null) {
- if (Flags.useSelfSyncTransactionForLayer() && mSyncState != SYNC_STATE_NONE) {
+ if (mSyncState != SYNC_STATE_NONE) {
// When this container needs to be synced, assign layer with its own sync
// transaction to avoid out of ordering when merge.
// Still use the passed-in transaction for non-sync case, such as building finish
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1d8d867f8dcb..0d434f51e082 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -561,7 +561,7 @@ class WindowStateAnimator {
break;
}
if (attr >= 0) {
- a = mWin.getDisplayContent().mAppTransition.loadAnimationAttr(
+ a = mWin.mDisplayContent.mTransitionAnimation.loadAnimationAttr(
mWin.mAttrs, attr, TRANSIT_OLD_NONE);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index a81a0b3251c8..4b98a723fc2d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -50,6 +50,7 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
+import android.util.PrintWriterPrinter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -1484,5 +1485,12 @@ class ActiveAdmin {
pw.print("mProvisioningContext=");
pw.println(mProvisioningContext);
}
+
+ if (info != null) {
+ pw.println("DeviceAdminInfo:");
+ pw.increaseIndent();
+ info.dump(new PrintWriterPrinter(pw), "");
+ pw.decreaseIndent();
+ }
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 860b6fb1dcd1..788b3b883160 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -366,6 +366,8 @@ public final class SystemServer implements Dumpable {
"com.android.clockwork.time.WearTimeService";
private static final String WEAR_SETTINGS_SERVICE_CLASS =
"com.android.clockwork.settings.WearSettingsService";
+ private static final String WEAR_GESTURE_SERVICE_CLASS =
+ "com.android.clockwork.gesture.WearGestureService";
private static final String WRIST_ORIENTATION_SERVICE_CLASS =
"com.android.clockwork.wristorientation.WristOrientationService";
private static final String IOT_SERVICE_CLASS =
@@ -2844,6 +2846,13 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(WRIST_ORIENTATION_SERVICE_CLASS);
t.traceEnd();
}
+
+ if (android.server.Flags.wearGestureApi()
+ && SystemProperties.getBoolean("config.enable_gesture_api", false)) {
+ t.traceBegin("StartWearGestureService");
+ mSystemServiceManager.startService(WEAR_GESTURE_SERVICE_CLASS);
+ t.traceEnd();
+ }
}
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED)) {
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 86ccd878de7c..7a6bd75e5893 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -65,4 +65,12 @@ flag {
namespace: "package_manager_service"
description: "Remove AppIntegrityManagerService"
bug: "364200023"
+}
+
+flag {
+ name: "wear_gesture_api"
+ namespace: "wear_frameworks"
+ description: "Whether the Wear Gesture API is available."
+ bug: "396154116"
+ is_exported: true
} \ No newline at end of file
diff --git a/services/proguard.flags b/services/proguard.flags
index 8d8b418ced0b..dd3757c9e360 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -59,6 +59,7 @@
# Referenced in wear-service
-keep public class com.android.server.wm.WindowManagerInternal { *; }
+-keep public class com.android.server.wm.WindowManagerInternal$WindowFocusChangeListener { *; }
# JNI keep rules
# The global keep rule for native methods allows stripping of such methods if they're unreferenced
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 2dd16f68dc56..80a3a8788d80 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -109,6 +109,7 @@ import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.backup.BackupAgentConnectionManager;
import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.BackupWakeLock;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
@@ -2412,7 +2413,7 @@ public class KeyValueBackupTaskTest {
KeyValueBackupTask task = spy(createKeyValueBackupTask(transportMock, PACKAGE_1));
doNothing().when(task).waitCancel();
- task.handleCancel(true);
+ task.handleCancel(CancellationReason.EXTERNAL);
InOrder inOrder = inOrder(task);
inOrder.verify(task).markCancel();
@@ -2420,12 +2421,14 @@ public class KeyValueBackupTaskTest {
}
@Test
- public void testHandleCancel_whenCancelAllFalse_throws() throws Exception {
+ public void testHandleCancel_timeout_throws() throws Exception {
TransportMock transportMock = setUpInitializedTransport(mTransport);
setUpAgentWithData(PACKAGE_1);
KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
- expectThrows(IllegalArgumentException.class, () -> task.handleCancel(false));
+ expectThrows(
+ IllegalArgumentException.class,
+ () -> task.handleCancel(CancellationReason.TIMEOUT));
}
/** Do not update backup token if no data was moved. */
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/util/IgnoreableExpect.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/util/IgnoreableExpect.kt
index afb18f5be669..5c9ba401bf88 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/util/IgnoreableExpect.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/util/IgnoreableExpect.kt
@@ -32,7 +32,7 @@ internal class IgnoreableExpect : TestRule {
private var ignore = false
- override fun apply(base: Statement?, description: Description?): Statement {
+ override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun evaluate() {
ignore = false
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 65585d06ff06..1f8ccde98d35 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -3914,6 +3914,7 @@ public class DisplayManagerServiceTest {
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerService.BinderService displayManagerBinderService =
displayManager.new BinderService();
+ DisplayManagerInternal localService = displayManager.new LocalService();
Handler handler = displayManager.getDisplayHandler();
waitForIdleHandler(handler);
@@ -3922,8 +3923,8 @@ public class DisplayManagerServiceTest {
INTERNAL_EVENT_FLAG_TOPOLOGY_UPDATED);
waitForIdleHandler(handler);
- var topology = initDisplayTopology(displayManager, displayManagerBinderService, callback,
- handler, /*shouldEmitTopologyChangeEvent=*/ true);
+ var topology = initDisplayTopology(displayManager, displayManagerBinderService,
+ localService, callback, handler, /*shouldEmitTopologyChangeEvent=*/ true);
callback.clear();
callback.expectsEvent(TOPOLOGY_CHANGED_EVENT);
displayManagerBinderService.setDisplayTopology(topology);
@@ -3938,6 +3939,7 @@ public class DisplayManagerServiceTest {
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerService.BinderService displayManagerBinderService =
displayManager.new BinderService();
+ DisplayManagerInternal localService = displayManager.new LocalService();
Handler handler = displayManager.getDisplayHandler();
waitForIdleHandler(handler);
@@ -3947,8 +3949,8 @@ public class DisplayManagerServiceTest {
STANDARD_DISPLAY_EVENTS);
waitForIdleHandler(handler);
- var topology = initDisplayTopology(displayManager, displayManagerBinderService, callback,
- handler, /*shouldEmitTopologyChangeEvent=*/ false);
+ var topology = initDisplayTopology(displayManager, displayManagerBinderService,
+ localService, callback, handler, /*shouldEmitTopologyChangeEvent=*/ false);
callback.clear();
callback.expectsEvent(TOPOLOGY_CHANGED_EVENT); // should not happen
displayManagerBinderService.setDisplayTopology(topology);
@@ -4706,15 +4708,16 @@ public class DisplayManagerServiceTest {
private DisplayTopology initDisplayTopology(DisplayManagerService displayManager,
DisplayManagerService.BinderService displayManagerBinderService,
- FakeDisplayManagerCallback callback,
+ DisplayManagerInternal localService, FakeDisplayManagerCallback callback,
Handler handler, boolean shouldEmitTopologyChangeEvent) {
Settings.Global.putInt(mContext.getContentResolver(),
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 1);
callback.expectsEvent(TOPOLOGY_CHANGED_EVENT);
FakeDisplayDevice displayDevice0 =
- createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL);
+ createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL);
int displayId0 = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
displayDevice0);
+ waitForIdleHandler(handler);
if (shouldEmitTopologyChangeEvent) {
callback.waitForExpectedEvent();
} else {
@@ -4728,6 +4731,11 @@ public class DisplayManagerServiceTest {
int displayId1 = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
displayDevice1);
waitForIdleHandler(handler);
+ // Non-default display should not be added until onDisplayBelongToTopologyChanged is called
+ // with true
+ callback.waitForNonExpectedEvent();
+ localService.onDisplayBelongToTopologyChanged(displayId1, true);
+ waitForIdleHandler(handler);
if (shouldEmitTopologyChangeEvent) {
callback.waitForExpectedEvent();
} else {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
index 3c134b5d5482..6dc7361e5366 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
@@ -47,7 +47,7 @@ class DisplayTopologyCoordinatorTest {
private val mockTopology = mock<DisplayTopology>()
private val mockTopologyCopy = mock<DisplayTopology>()
private val mockTopologyGraph = mock<DisplayTopologyGraph>()
- private val mockIsExtendedDisplayEnabled = mock<() -> Boolean>()
+ private val mockIsExtendedDisplayAllowed = mock<() -> Boolean>()
private val mockTopologySavedCallback = mock<() -> Unit>()
private val mockTopologyChangedCallback =
mock<(android.util.Pair<DisplayTopology, DisplayTopologyGraph>) -> Unit>()
@@ -73,10 +73,10 @@ class DisplayTopologyCoordinatorTest {
) =
mockTopologyStore
}
- whenever(mockIsExtendedDisplayEnabled()).thenReturn(true)
+ whenever(mockIsExtendedDisplayAllowed()).thenReturn(true)
whenever(mockTopology.copy()).thenReturn(mockTopologyCopy)
whenever(mockTopologyCopy.getGraph(any())).thenReturn(mockTopologyGraph)
- coordinator = DisplayTopologyCoordinator(injector, mockIsExtendedDisplayEnabled,
+ coordinator = DisplayTopologyCoordinator(injector, mockIsExtendedDisplayAllowed,
mockTopologyChangedCallback, topologyChangeExecutor, DisplayManagerService.SyncRoot(),
mockTopologySavedCallback)
}
@@ -195,7 +195,7 @@ class DisplayTopologyCoordinatorTest {
@Test
fun addDisplay_external_extendedDisplaysDisabled() {
- whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+ whenever(mockIsExtendedDisplayAllowed()).thenReturn(false)
for (displayInfo in displayInfos) {
coordinator.onDisplayAdded(displayInfo)
@@ -208,7 +208,7 @@ class DisplayTopologyCoordinatorTest {
@Test
fun addDisplay_overlay_extendedDisplaysDisabled() {
displayInfos[0].type = Display.TYPE_OVERLAY
- whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+ whenever(mockIsExtendedDisplayAllowed()).thenReturn(false)
for (displayInfo in displayInfos) {
coordinator.onDisplayAdded(displayInfo)
@@ -220,17 +220,6 @@ class DisplayTopologyCoordinatorTest {
}
@Test
- fun addDisplay_notInDefaultDisplayGroup() {
- displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1
-
- coordinator.onDisplayAdded(displayInfos[0])
-
- verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
- verify(mockTopologyChangedCallback, never()).invoke(any())
- verify(mockTopologyStore, never()).restoreTopology(any())
- }
-
- @Test
fun updateDisplay() {
whenever(mockTopology.updateDisplay(eq(displayInfos[0].displayId), anyFloat(), anyFloat()))
.thenReturn(true)
@@ -325,7 +314,7 @@ class DisplayTopologyCoordinatorTest {
@Test
fun updateDisplay_external_extendedDisplaysDisabled() {
- whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+ whenever(mockIsExtendedDisplayAllowed()).thenReturn(false)
for (displayInfo in displayInfos) {
coordinator.onDisplayChanged(displayInfo)
@@ -339,7 +328,7 @@ class DisplayTopologyCoordinatorTest {
@Test
fun updateDisplay_overlay_extendedDisplaysDisabled() {
displayInfos[0].type = Display.TYPE_OVERLAY
- whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+ whenever(mockIsExtendedDisplayAllowed()).thenReturn(false)
coordinator.onDisplayChanged(displayInfos[0])
@@ -349,17 +338,6 @@ class DisplayTopologyCoordinatorTest {
}
@Test
- fun updateDisplay_notInDefaultDisplayGroup() {
- displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1
-
- coordinator.onDisplayChanged(displayInfos[0])
-
- verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
- verify(mockTopologyCopy, never()).getGraph(any())
- verify(mockTopologyChangedCallback, never()).invoke(any())
- }
-
- @Test
fun removeDisplay() {
addDisplay()
diff --git a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 22c10f967398..067230a66228 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -113,10 +112,10 @@ public class ColorDisplayServiceTest {
doReturn(mContext).when(mContext).getApplicationContext();
final Resources res = Mockito.spy(mContext.getResources());
+ doReturn(res).when(mContext).getResources();
doReturn(MINIMAL_COLOR_MODES).when(res).getIntArray(R.array.config_availableColorModes);
doReturn(true).when(res).getBoolean(R.bool.config_nightDisplayAvailable);
doReturn(true).when(res).getBoolean(R.bool.config_displayWhiteBalanceAvailable);
- when(mContext.getResources()).thenReturn(res);
mResourcesSpy = res;
mUserId = ActivityManager.getCurrentUser();
@@ -1105,10 +1104,11 @@ public class ColorDisplayServiceTest {
@Test
public void compositionColorSpaces_noResources() {
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
- .thenReturn(new int[] {});
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
- .thenReturn(new int[] {});
+ doReturn(new int[] {}).when(mResourcesSpy)
+ .getIntArray(R.array.config_displayCompositionColorModes);
+ doReturn(new int[] {}).when(mResourcesSpy)
+ .getIntArray(R.array.config_displayCompositionColorSpaces);
+
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
@@ -1118,16 +1118,15 @@ public class ColorDisplayServiceTest {
@Test
public void compositionColorSpaces_invalidResources() {
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
- .thenReturn(new int[] {
- ColorDisplayManager.COLOR_MODE_NATURAL,
- // Missing second color mode
- });
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
- .thenReturn(new int[] {
- Display.COLOR_MODE_SRGB,
- Display.COLOR_MODE_DISPLAY_P3
- });
+ doReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL,
+ // Missing second color mode
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorModes);
+ doReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ Display.COLOR_MODE_DISPLAY_P3
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorSpaces);
+
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
@@ -1137,14 +1136,13 @@ public class ColorDisplayServiceTest {
@Test
public void compositionColorSpaces_validResources_validColorMode() {
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
- .thenReturn(new int[] {
- ColorDisplayManager.COLOR_MODE_NATURAL
- });
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
- .thenReturn(new int[] {
- Display.COLOR_MODE_SRGB,
- });
+ doReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorModes);
+ doReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorSpaces);
+
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
@@ -1154,14 +1152,13 @@ public class ColorDisplayServiceTest {
@Test
public void compositionColorSpaces_validResources_invalidColorMode() {
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
- .thenReturn(new int[] {
- ColorDisplayManager.COLOR_MODE_NATURAL
- });
- when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
- .thenReturn(new int[] {
- Display.COLOR_MODE_SRGB,
- });
+ doReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorModes);
+ doReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ }).when(mResourcesSpy).getIntArray(R.array.config_displayCompositionColorSpaces);
+
setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
startService();
verify(mDisplayTransformManager).setColorMode(
@@ -1171,8 +1168,7 @@ public class ColorDisplayServiceTest {
@Test
public void getColorMode_noAvailableModes_returnsNotSet() {
- when(mResourcesSpy.getIntArray(R.array.config_availableColorModes))
- .thenReturn(new int[] {});
+ doReturn(new int[] {}).when(mResourcesSpy).getIntArray(R.array.config_availableColorModes);
startService();
verify(mDisplayTransformManager, never()).setColorMode(anyInt(), any(), any(), anyInt());
assertThat(mBinderService.getColorMode()).isEqualTo(-1);
@@ -1197,16 +1193,17 @@ public class ColorDisplayServiceTest {
@Test
public void sliderScalesWithinRange() {
+ doReturn(true).when(mRbcSpy).isAvailable(mContext);
+
+ doReturn(85).when(mResourcesSpy).getInteger(
+ R.integer.config_reduceBrightColorsStrengthMax);
+ doReturn(10).when(mResourcesSpy).getInteger(
+ R.integer.config_reduceBrightColorsStrengthMin);
+ doReturn(44).when(mResourcesSpy).getInteger(
+ R.integer.config_reduceBrightColorsStrengthDefault);
+
// setup
startService();
- reset(mRbcSpy);
- doReturn(true).when(mRbcSpy).isAvailable(mContext);
- when(mContext.getResources().getInteger(
- R.integer.config_reduceBrightColorsStrengthMax)).thenReturn(85);
- when(mContext.getResources().getInteger(
- R.integer.config_reduceBrightColorsStrengthMin)).thenReturn(10);
- when(mContext.getResources().getInteger(
- R.integer.config_reduceBrightColorsStrengthDefault)).thenReturn(44);
// Valid value test //
// set on, and to 90% of range
diff --git a/services/tests/media/mediarouterservicetest/Android.bp b/services/tests/media/mediarouterservicetest/Android.bp
index aed3af6b69f6..f149f2ec8d56 100644
--- a/services/tests/media/mediarouterservicetest/Android.bp
+++ b/services/tests/media/mediarouterservicetest/Android.bp
@@ -9,6 +9,10 @@ package {
android_test {
name: "MediaRouterServiceTests",
+ defaults: [
+ // For ExtendedMockito dependencies.
+ "modules-utils-testable-device-config-defaults",
+ ],
srcs: [
"src/**/*.java",
],
@@ -23,12 +27,17 @@ android_test {
"services.core",
"truth",
],
+ libs: [
+ "android.test.base.stubs",
+ "android.test.runner.stubs",
+ ],
platform_apis: true,
test_suites: [
// "device-tests",
"general-tests",
+ "mts-statsd",
],
certificate: "platform",
@@ -36,4 +45,5 @@ android_test {
optimize: {
enabled: false,
},
+ min_sdk_version: "30",
}
diff --git a/services/tests/media/mediarouterservicetest/AndroidTest.xml b/services/tests/media/mediarouterservicetest/AndroidTest.xml
index b0656816b701..646812b076d6 100644
--- a/services/tests/media/mediarouterservicetest/AndroidTest.xml
+++ b/services/tests/media/mediarouterservicetest/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-tag" value="MediaRouterServiceTests" />
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-instrumentation" />
+ <option name="test-suite-tag" value="mts" />
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
@@ -26,7 +27,7 @@
<option name="install-arg" value="-t" />
</target_preparer>
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.server.media.tests" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
diff --git a/services/tests/media/mediarouterservicetest/src/com/android/server/media/MediaRouterMetricLoggerTest.java b/services/tests/media/mediarouterservicetest/src/com/android/server/media/MediaRouterMetricLoggerTest.java
new file mode 100644
index 000000000000..5e401aefc24c
--- /dev/null
+++ b/services/tests/media/mediarouterservicetest/src/com/android/server/media/MediaRouterMetricLoggerTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import static android.media.MediaRoute2ProviderService.REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA;
+import static android.media.MediaRoute2ProviderService.REASON_INVALID_COMMAND;
+import static android.media.MediaRoute2ProviderService.REASON_NETWORK_ERROR;
+import static android.media.MediaRoute2ProviderService.REASON_REJECTED;
+import static android.media.MediaRoute2ProviderService.REASON_ROUTE_NOT_AVAILABLE;
+import static android.media.MediaRoute2ProviderService.REASON_UNIMPLEMENTED;
+import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_FAILED_TO_REROUTE_SYSTEM_MEDIA;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_NETWORK_ERROR;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_REJECTED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTE_NOT_AVAILABLE;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNIMPLEMENTED;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNKNOWN_ERROR;
+import static com.android.server.media.MediaRouterStatsLog.MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED;
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.runner.AndroidJUnit4;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class MediaRouterMetricLoggerTest {
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule =
+ new ExtendedMockitoRule.Builder(this).mockStatic(MediaRouterStatsLog.class).build();
+
+ private MediaRouterMetricLogger mLogger;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLogger = new MediaRouterMetricLogger();
+ }
+
+ @Test
+ public void addRequestInfo_addsRequestInfoToCache() {
+ long requestId = 123;
+ int eventType = MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+
+ mLogger.addRequestInfo(requestId, eventType);
+
+ assertThat(mLogger.getRequestCacheSize()).isEqualTo(1);
+ }
+
+ @Test
+ public void removeRequestInfo_removesRequestInfoFromCache() {
+ long requestId = 123;
+ int eventType = MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+ mLogger.addRequestInfo(requestId, eventType);
+
+ mLogger.removeRequestInfo(requestId);
+
+ assertThat(mLogger.getRequestCacheSize()).isEqualTo(0);
+ }
+
+ @Test
+ public void logOperationFailure_logsOperationFailure() {
+ int eventType = MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+ int result = MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_REJECTED;
+ mLogger.logOperationFailure(eventType, result);
+ verify(
+ () ->
+ MediaRouterStatsLog.write( // Use ExtendedMockito.verify and lambda
+ MEDIA_ROUTER_EVENT_REPORTED, eventType, result));
+ }
+
+ @Test
+ public void logRequestResult_logsRequestResult() {
+ long requestId = 123;
+ int eventType = MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION;
+ int result = MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_SUCCESS;
+ mLogger.addRequestInfo(requestId, eventType);
+
+ mLogger.logRequestResult(requestId, result);
+
+ assertThat(mLogger.getRequestCacheSize()).isEqualTo(0);
+ verify(
+ () ->
+ MediaRouterStatsLog.write( // Use ExtendedMockito.verify and lambda
+ MEDIA_ROUTER_EVENT_REPORTED, eventType, result));
+ }
+
+ @Test
+ public void convertResultFromReason_returnsCorrectResult() {
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_UNKNOWN_ERROR))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNKNOWN_ERROR);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_REJECTED))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_REJECTED);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_NETWORK_ERROR))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_NETWORK_ERROR);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_ROUTE_NOT_AVAILABLE))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_ROUTE_NOT_AVAILABLE);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_INVALID_COMMAND))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_INVALID_COMMAND);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(REASON_UNIMPLEMENTED))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNIMPLEMENTED);
+ assertThat(
+ MediaRouterMetricLogger.convertResultFromReason(
+ REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA))
+ .isEqualTo(
+ MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_FAILED_TO_REROUTE_SYSTEM_MEDIA);
+ assertThat(MediaRouterMetricLogger.convertResultFromReason(-1))
+ .isEqualTo(MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
+ }
+
+ @Test
+ public void getRequestCacheSize_returnsCorrectSize() {
+ assertThat(mLogger.getRequestCacheSize()).isEqualTo(0);
+ mLogger.addRequestInfo(
+ 123, MEDIA_ROUTER_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_CREATE_SESSION);
+ assertThat(mLogger.getRequestCacheSize()).isEqualTo(1);
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 340115a7d465..5d8f57866f7d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -43,6 +43,7 @@ import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -107,6 +108,7 @@ import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -698,7 +700,7 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
- @EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
+ @EnableFlags({Flags.FLAG_USE_CPU_TIME_CAPABILITY, Flags.FLAG_PROTOTYPE_AGGRESSIVE_FREEZING})
public void testUpdateOomAdjFreezeState_bindingFromShortFgs() {
// Setting up a started short FGS within app1.
final ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(mService);
@@ -744,6 +746,44 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
@EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
+ @DisableFlags(Flags.FLAG_PROTOTYPE_AGGRESSIVE_FREEZING)
+ public void testUpdateOomAdjFreezeState_bindingFromFgs() {
+ final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ mProcessStateController.setHasForegroundServices(app.mServices, true,
+ FOREGROUND_SERVICE_TYPE_SPECIAL_USE, false);
+
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ // App with a foreground service binds to app2
+ bindService(app2, app, null, null, 0, mock(IBinder.class));
+
+ setProcessesToLru(app, app2);
+ updateOomAdj(app);
+
+ assertCpuTime(app);
+ assertCpuTime(app2);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ @EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
+ @DisableFlags(Flags.FLAG_PROTOTYPE_AGGRESSIVE_FREEZING)
+ public void testUpdateOomAdjFreezeState_soloFgs() {
+ final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ mProcessStateController.setHasForegroundServices(app.mServices, true,
+ FOREGROUND_SERVICE_TYPE_SPECIAL_USE, false);
+
+ setProcessesToLru(app);
+ updateOomAdj(app);
+
+ assertCpuTime(app);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ @EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
public void testUpdateOomAdjFreezeState_receivers() {
final ProcessRecord app = makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
index d6349fc0651f..ab3784b07e10 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
@@ -32,7 +32,6 @@ import static com.android.server.am.PendingIntentRecord.CANCEL_REASON_SUPERSEDED
import static com.android.server.am.PendingIntentRecord.CANCEL_REASON_USER_STOPPED;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.cancelReasonToString;
-import static com.android.window.flags.Flags.balClearAllowlistDuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -216,9 +215,7 @@ public class PendingIntentControllerTest {
pir.getAllowlistDurationLocked(token);
assertNotNull(allowlistDurationLockedAfterClear);
assertEquals(1000, allowlistDurationLockedAfterClear.duration);
- assertEquals(balClearAllowlistDuration()
- ? TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED
- : TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
allowlistDurationLocked.type);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
index 8aaa72339c5b..33bd95ec9f5b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
@@ -51,6 +51,7 @@ import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupRestoreTask.CancellationReason;
import com.android.server.backup.internal.LifecycleOperationStorage;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
@@ -368,9 +369,12 @@ public class BackupAgentConnectionManagerTest {
mConnectionManager.agentDisconnected(TEST_PACKAGE);
mTestThread.join();
- verify(mUserBackupManagerService).handleCancel(eq(123), eq(true));
- verify(mUserBackupManagerService).handleCancel(eq(456), eq(true));
- verify(mUserBackupManagerService).handleCancel(eq(789), eq(true));
+ verify(mUserBackupManagerService)
+ .handleCancel(eq(123), eq(CancellationReason.AGENT_DISCONNECTED));
+ verify(mUserBackupManagerService)
+ .handleCancel(eq(456), eq(CancellationReason.AGENT_DISCONNECTED));
+ verify(mUserBackupManagerService)
+ .handleCancel(eq(789), eq(CancellationReason.AGENT_DISCONNECTED));
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
index e030b3f19e4f..16adf8f8c7fe 100644
--- a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
@@ -60,4 +60,8 @@ android_test {
"mts-crashrecovery",
],
min_sdk_version: "36",
+
+ // Test coverage system runs on different devices. Need to
+ // compile for all architecture.
+ compile_multilib: "both",
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java
index 8ce05e2fa115..c9f86b04be22 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java
@@ -23,7 +23,6 @@ import static android.hardware.display.DisplayManagerInternal.DisplayPowerReques
import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
-import static com.android.server.power.ScreenUndimDetector.DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS;
import static com.android.server.power.ScreenUndimDetector.KEY_KEEP_SCREEN_ON_ENABLED;
import static com.android.server.power.ScreenUndimDetector.KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS;
import static com.android.server.power.ScreenUndimDetector.KEY_UNDIMS_REQUIRED;
@@ -49,6 +48,7 @@ import org.junit.runners.JUnit4;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
* Tests for {@link com.android.server.power.ScreenUndimDetector}
@@ -61,7 +61,8 @@ public class ScreenUndimDetectorTest {
POLICY_DIM,
POLICY_BRIGHT);
private static final int OTHER_DISPLAY_GROUP = DEFAULT_DISPLAY_GROUP + 1;
-
+ private static final long DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS =
+ TimeUnit.MINUTES.toMillis(5);
@ClassRule
public static final TestableContext sContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
@@ -88,7 +89,8 @@ public class ScreenUndimDetectorTest {
@Before
public void setup() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
+ DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+ KEY_KEEP_SCREEN_ON_ENABLED, Boolean.TRUE.toString(), false /*makeDefault*/);
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_UNDIMS_REQUIRED,
Integer.toString(1), false /*makeDefault*/);
@@ -108,10 +110,10 @@ public class ScreenUndimDetectorTest {
@Test
public void recordScreenPolicy_disabledByFlag_noop() {
+ setup();
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_KEEP_SCREEN_ON_ENABLED, Boolean.FALSE.toString(), false /*makeDefault*/);
mScreenUndimDetector.readValuesFromDeviceConfig();
-
mScreenUndimDetector.recordScreenPolicy(DEFAULT_DISPLAY_GROUP, POLICY_DIM);
mScreenUndimDetector.recordScreenPolicy(DEFAULT_DISPLAY_GROUP, POLICY_BRIGHT);
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
index 36b064b9b090..7c02370ef758 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
@@ -58,6 +58,10 @@ android_test {
"mts-crashrecovery",
],
min_sdk_version: "36",
+
+ // Test coverage system runs on different devices. Need to
+ // compile for all architecture.
+ compile_multilib: "both",
}
test_module_config {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index 5165e34c7fcd..fc864dd230d9 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
@@ -330,31 +331,24 @@ public class BatteryStatsHistoryTest {
return invocation.callRealMethod();
}).when(mHistory).readFragmentToParcel(any(), any());
- // Prepare history for iteration
- mHistory.iterate(0, MonotonicClock.UNDEFINED);
-
- Parcel parcel = mHistory.getNextParcel(0, Long.MAX_VALUE);
- assertThat(parcel).isNotNull();
- assertThat(mReadFiles).containsExactly("123.bh");
-
- // Skip to the end to force reading the next parcel
- parcel.setDataPosition(parcel.dataSize());
- mReadFiles.clear();
- parcel = mHistory.getNextParcel(0, Long.MAX_VALUE);
- assertThat(parcel).isNotNull();
- assertThat(mReadFiles).containsExactly("1000.bh");
-
- parcel.setDataPosition(parcel.dataSize());
- mReadFiles.clear();
- parcel = mHistory.getNextParcel(0, Long.MAX_VALUE);
- assertThat(parcel).isNotNull();
- assertThat(mReadFiles).containsExactly("2000.bh");
+ int eventsRead = 0;
+ BatteryStatsHistoryIterator iterator = mHistory.iterate(0, MonotonicClock.UNDEFINED);
+ while (iterator.hasNext()) {
+ HistoryItem item = iterator.next();
+ if (item.eventCode == HistoryItem.EVENT_JOB_START) {
+ eventsRead++;
+ assertThat(mReadFiles).containsExactly("123.bh");
+ } else if (item.eventCode == HistoryItem.EVENT_JOB_FINISH) {
+ eventsRead++;
+ assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
+ } else if (item.eventCode == HistoryItem.EVENT_ALARM) {
+ eventsRead++;
+ assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh");
+ }
+ }
- parcel.setDataPosition(parcel.dataSize());
- mReadFiles.clear();
- parcel = mHistory.getNextParcel(0, Long.MAX_VALUE);
- assertThat(parcel).isNull();
- assertThat(mReadFiles).isEmpty();
+ assertThat(eventsRead).isEqualTo(3);
+ assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh", "3000.bh");
}
@Test
@@ -372,25 +366,19 @@ public class BatteryStatsHistoryTest {
return invocation.callRealMethod();
}).when(mHistory).readFragmentToParcel(any(), any());
- // Prepare history for iteration
- mHistory.iterate(1000, 3000);
-
- Parcel parcel = mHistory.getNextParcel(1000, 3000);
- assertThat(parcel).isNotNull();
- assertThat(mReadFiles).containsExactly("1000.bh");
-
- // Skip to the end to force reading the next parcel
- parcel.setDataPosition(parcel.dataSize());
- mReadFiles.clear();
- parcel = mHistory.getNextParcel(1000, 3000);
- assertThat(parcel).isNotNull();
- assertThat(mReadFiles).containsExactly("2000.bh");
+ BatteryStatsHistoryIterator iterator = mHistory.iterate(1000, 3000);
+ while (iterator.hasNext()) {
+ HistoryItem item = iterator.next();
+ if (item.eventCode == HistoryItem.EVENT_JOB_START) {
+ fail("Event outside the range");
+ } else if (item.eventCode == HistoryItem.EVENT_JOB_FINISH) {
+ assertThat(mReadFiles).containsExactly("1000.bh");
+ } else if (item.eventCode == HistoryItem.EVENT_ALARM) {
+ fail("Event outside the range");
+ }
+ }
- parcel.setDataPosition(parcel.dataSize());
- mReadFiles.clear();
- parcel = mHistory.getNextParcel(1000, 3000);
- assertThat(parcel).isNull();
- assertThat(mReadFiles).isEmpty();
+ assertThat(mReadFiles).containsExactly("1000.bh", "2000.bh");
}
private void prepareMultiFileHistory() {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
index f7b16c808c50..dd089fcb1d70 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
@@ -201,11 +201,11 @@ public class AutoclickTypePanelTest {
public void moveToNextCorner_positionButton_rotatesThroughAllPositions() {
// Define all positions in sequence
int[][] expectedPositions = {
- {0, Gravity.END | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90},
- {1, Gravity.START | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90},
- {2, Gravity.START | Gravity.TOP, /*x=*/ 15, /*y=*/ 30},
- {3, Gravity.END | Gravity.TOP, /*x=*/ 15, /*y=*/ 30},
- {0, Gravity.END | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90}
+ {CORNER_BOTTOM_RIGHT, Gravity.END | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90},
+ {CORNER_BOTTOM_LEFT, Gravity.START | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90},
+ {CORNER_TOP_LEFT, Gravity.START | Gravity.TOP, /*x=*/ 15, /*y=*/ 30},
+ {CORNER_TOP_RIGHT, Gravity.END | Gravity.TOP, /*x=*/ 15, /*y=*/ 30},
+ {CORNER_BOTTOM_RIGHT, Gravity.END | Gravity.BOTTOM, /*x=*/ 15, /*y=*/ 90}
};
// Check initial position
@@ -270,7 +270,7 @@ public class AutoclickTypePanelTest {
int screenWidth = mTestableContext.getResources().getDisplayMetrics().widthPixels;
// Verify initial corner is bottom-right.
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting())
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting())
.isEqualTo(CORNER_BOTTOM_RIGHT);
dispatchDragSequence(contentView,
@@ -279,7 +279,7 @@ public class AutoclickTypePanelTest {
// Verify snapping to the right.
assertThat(params.gravity).isEqualTo(Gravity.END | Gravity.TOP);
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting())
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting())
.isEqualTo(CORNER_TOP_RIGHT);
}
@@ -293,7 +293,7 @@ public class AutoclickTypePanelTest {
int screenWidth = mTestableContext.getResources().getDisplayMetrics().widthPixels;
// Verify initial corner is bottom-right.
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting())
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting())
.isEqualTo(CORNER_BOTTOM_RIGHT);
dispatchDragSequence(contentView,
@@ -302,7 +302,7 @@ public class AutoclickTypePanelTest {
// Verify snapping to the left.
assertThat(params.gravity).isEqualTo(Gravity.START | Gravity.TOP);
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting())
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting())
.isEqualTo(CORNER_BOTTOM_LEFT);
}
@@ -319,7 +319,7 @@ public class AutoclickTypePanelTest {
// Verify panel is positioned at default bottom-right corner.
WindowManager.LayoutParams params = panel.getLayoutParamsForTesting();
- assertThat(panel.getCurrentCornerIndexForTesting()).isEqualTo(CORNER_BOTTOM_RIGHT);
+ assertThat(panel.getCurrentCornerForTesting()).isEqualTo(CORNER_BOTTOM_RIGHT);
assertThat(params.gravity).isEqualTo(Gravity.END | Gravity.BOTTOM);
assertThat(params.x).isEqualTo(15); // Default edge margin.
assertThat(params.y).isEqualTo(90); // Default bottom offset.
@@ -353,7 +353,7 @@ public class AutoclickTypePanelTest {
assertThat(params.gravity).isEqualTo(Gravity.START | Gravity.TOP);
assertThat(params.x).isEqualTo(15);
assertThat(params.y).isEqualTo(30);
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting()).isEqualTo(
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting()).isEqualTo(
CORNER_TOP_LEFT);
}
@@ -392,7 +392,7 @@ public class AutoclickTypePanelTest {
assertThat(params.gravity).isEqualTo(Gravity.START | Gravity.TOP);
assertThat(params.x).isEqualTo(15); // PANEL_EDGE_MARGIN
assertThat(params.y).isEqualTo(panelLocation[1] + 10);
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting()).isEqualTo(
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting()).isEqualTo(
CORNER_BOTTOM_LEFT);
}
@@ -453,7 +453,7 @@ public class AutoclickTypePanelTest {
private void verifyPanelPosition(int[] expectedPosition) {
WindowManager.LayoutParams params = mAutoclickTypePanel.getLayoutParamsForTesting();
- assertThat(mAutoclickTypePanel.getCurrentCornerIndexForTesting()).isEqualTo(
+ assertThat(mAutoclickTypePanel.getCurrentCornerForTesting()).isEqualTo(
expectedPosition[0]);
assertThat(params.gravity).isEqualTo(expectedPosition[1]);
assertThat(params.x).isEqualTo(expectedPosition[2]);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index ac27a971102a..9ec99c651691 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -30,7 +30,10 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -248,6 +251,40 @@ public class FullScreenMagnificationControllerTest {
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
+ public void testRegister_RegistersPointerMotionFilter() {
+ register(DISPLAY_0);
+
+ verify(mMockInputManager).registerAccessibilityPointerMotionFilter(
+ any(InputManagerInternal.AccessibilityPointerMotionFilter.class));
+
+ // If a filter is already registered, adding a display won't invoke another filter
+ // registration.
+ clearInvocations(mMockInputManager);
+ register(DISPLAY_1);
+ register(INVALID_DISPLAY);
+
+ verify(mMockInputManager, times(0)).registerAccessibilityPointerMotionFilter(
+ any(InputManagerInternal.AccessibilityPointerMotionFilter.class));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
+ public void testUnregister_UnregistersPointerMotionFilter() {
+ register(DISPLAY_0);
+ register(DISPLAY_1);
+ clearInvocations(mMockInputManager);
+
+ mFullScreenMagnificationController.unregister(DISPLAY_1);
+ // There's still an active display. Don't unregister yet.
+ verify(mMockInputManager, times(0)).registerAccessibilityPointerMotionFilter(
+ nullable(InputManagerInternal.AccessibilityPointerMotionFilter.class));
+
+ mFullScreenMagnificationController.unregister(DISPLAY_0);
+ verify(mMockInputManager, times(1)).registerAccessibilityPointerMotionFilter(isNull());
+ }
+
+ @Test
public void testInitialState_noMagnificationAndMagnificationRegionReadFromWindowManager() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
initialState_noMagnificationAndMagnificationRegionReadFromWindowManager(i);
@@ -699,6 +736,63 @@ public class FullScreenMagnificationControllerTest {
}
@Test
+ public void testSetOffset_whileMagnifying_offsetsMove() {
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ setOffset_whileMagnifying_offsetsMove(i);
+ resetMockWindowManager();
+ }
+ }
+
+ private void setOffset_whileMagnifying_offsetsMove(int displayId) {
+ register(displayId);
+ PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+ for (final float scale : new float[]{2.0f, 2.5f, 3.0f}) {
+ assertTrue(mFullScreenMagnificationController
+ .setScaleAndCenter(displayId, scale, startCenter.x, startCenter.y, true, false,
+ SERVICE_ID_1));
+ mMessageCapturingHandler.sendAllMessages();
+
+ for (final PointF center : new PointF[]{
+ INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER,
+ INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER}) {
+ Mockito.clearInvocations(mMockWindowManager);
+ PointF newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, center, scale);
+ mFullScreenMagnificationController.setOffset(displayId, newOffsets.x, newOffsets.y,
+ SERVICE_ID_1);
+ mMessageCapturingHandler.sendAllMessages();
+
+ MagnificationSpec expectedSpec = getMagnificationSpec(scale, newOffsets);
+ verify(mMockWindowManager)
+ .setMagnificationSpec(eq(displayId), argThat(closeTo(expectedSpec)));
+ assertEquals(center.x, mFullScreenMagnificationController.getCenterX(displayId),
+ 0.0);
+ assertEquals(center.y, mFullScreenMagnificationController.getCenterY(displayId),
+ 0.0);
+ verify(mMockValueAnimator, times(0)).start();
+ }
+ }
+ }
+
+ @Test
+ public void testSetOffset_whileNotMagnifying_hasNoEffect() {
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ setOffset_whileNotMagnifying_hasNoEffect(i);
+ resetMockWindowManager();
+ }
+ }
+
+ private void setOffset_whileNotMagnifying_hasNoEffect(int displayId) {
+ register(displayId);
+ Mockito.reset(mMockWindowManager);
+ MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
+ mFullScreenMagnificationController.setOffset(displayId, 100, 100, SERVICE_ID_1);
+ assertThat(getCurrentMagnificationSpec(displayId), closeTo(startSpec));
+ mFullScreenMagnificationController.setOffset(displayId, 200, 200, SERVICE_ID_1);
+ assertThat(getCurrentMagnificationSpec(displayId), closeTo(startSpec));
+ verifyNoMoreInteractions(mMockWindowManager);
+ }
+
+ @Test
@RequiresFlagsEnabled(Flags.FLAG_FULLSCREEN_FLING_GESTURE)
public void testStartFling_whileMagnifying_flings() throws InterruptedException {
for (int i = 0; i < DISPLAY_COUNT; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 5c126d1f5d3f..4ea5fcfd79c8 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -1419,6 +1419,12 @@ public class FullScreenMagnificationGestureHandlerTest {
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
+ public void testMouseMoveEventsDoNotMoveMagnifierViewport() {
+ runMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
public void testStylusMoveEventsDoNotMoveMagnifierViewport() {
runMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_STYLUS);
}
@@ -1467,11 +1473,28 @@ public class FullScreenMagnificationGestureHandlerTest {
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
+ public void testMouseHoverMoveEventsDoNotMoveMagnifierViewport() {
+ // Note that this means mouse hover shouldn't be handled here.
+ // FullScreenMagnificationPointerMotionEventFilter handles mouse input events.
+ runHoverMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
+ public void testStylusHoverMoveEventsDoNotMoveMagnifierViewport() {
+ // TODO(b/398984690): We will revisit the behavior.
+ runHoverMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
public void testMouseHoverMoveEventsMoveMagnifierViewport() {
runHoverMovesViewportTest(InputDevice.SOURCE_MOUSE);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
public void testStylusHoverMoveEventsMoveMagnifierViewport() {
runHoverMovesViewportTest(InputDevice.SOURCE_STYLUS);
}
@@ -1497,6 +1520,7 @@ public class FullScreenMagnificationGestureHandlerTest {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE_WITH_POINTER_MOTION_FILTER)
public void testMouseMoveEventsMoveMagnifierViewport() {
final EventCaptor eventCaptor = new EventCaptor();
mMgh.setNext(eventCaptor);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilterTest.java
new file mode 100644
index 000000000000..a8315d4eb3a5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationPointerMotionEventFilterTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.accessibility.magnification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class FullScreenMagnificationPointerMotionEventFilterTest {
+ @Mock
+ private FullScreenMagnificationController mMockFullScreenMagnificationController;
+
+ private FullScreenMagnificationPointerMotionEventFilter mFilter;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mFilter = new FullScreenMagnificationPointerMotionEventFilter(
+ mMockFullScreenMagnificationController);
+ }
+
+ @Test
+ public void inactiveDisplay_doNothing() {
+ when(mMockFullScreenMagnificationController.isActivated(anyInt())).thenReturn(false);
+
+ float[] delta = new float[]{1.f, 2.f};
+ float[] result = mFilter.filterPointerMotionEvent(delta[0], delta[1], 3.0f, 4.0f, 0);
+ assertThat(result).isEqualTo(delta);
+ }
+
+ @Test
+ public void testContinuousMove() {
+ when(mMockFullScreenMagnificationController.isActivated(anyInt())).thenReturn(true);
+ when(mMockFullScreenMagnificationController.getScale(anyInt())).thenReturn(3.f);
+
+ float[] delta = new float[]{5.f, 10.f};
+ float[] result = mFilter.filterPointerMotionEvent(delta[0], delta[1], 20.f, 30.f, 0);
+ assertThat(result).isEqualTo(delta);
+ // At the first cursor move, it goes to (20, 30) + (5, 10) = (25, 40). The scale is 3.0.
+ // The expected offset is (-25 * (3-1), -40 * (3-1)) = (-50, -80).
+ verify(mMockFullScreenMagnificationController)
+ .setOffset(eq(0), eq(-50.f), eq(-80.f), anyInt());
+
+ float[] delta2 = new float[]{10.f, 5.f};
+ float[] result2 = mFilter.filterPointerMotionEvent(delta2[0], delta2[1], 25.f, 40.f, 0);
+ assertThat(result2).isEqualTo(delta2);
+ // At the second cursor move, it goes to (25, 40) + (10, 5) = (35, 40). The scale is 3.0.
+ // The expected offset is (-35 * (3-1), -45 * (3-1)) = (-70, -90).
+ verify(mMockFullScreenMagnificationController)
+ .setOffset(eq(0), eq(-70.f), eq(-90.f), anyInt());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/appop/DiscreteAppOpXmlPersistenceTest.java b/services/tests/servicestests/src/com/android/server/appop/DiscreteAppOpXmlPersistenceTest.java
index ae973be17904..56f802b278c6 100644
--- a/services/tests/servicestests/src/com/android/server/appop/DiscreteAppOpXmlPersistenceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/DiscreteAppOpXmlPersistenceTest.java
@@ -89,8 +89,7 @@ public class DiscreteAppOpXmlPersistenceTest {
int attributionChainId = AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op, null, opFlags,
- uidState, accessTime, duration, attributionFlags, attributionChainId,
- DiscreteOpsXmlRegistry.ACCESS_TYPE_FINISH_OP);
+ uidState, accessTime, duration, attributionFlags, attributionChainId);
// Verify in-memory object is correct
fetchDiscreteOpsAndValidate(uid, packageName, op, deviceId, null, accessTime,
@@ -121,8 +120,7 @@ public class DiscreteAppOpXmlPersistenceTest {
int attributionChainId = 10;
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op, null, opFlags,
- uidState, accessTime, duration, attributionFlags, attributionChainId,
- DiscreteOpsXmlRegistry.ACCESS_TYPE_START_OP);
+ uidState, accessTime, duration, attributionFlags, attributionChainId);
fetchDiscreteOpsAndValidate(uid, packageName, op, deviceId, null, accessTime,
duration, uidState, opFlags, attributionFlags, attributionChainId);
diff --git a/services/tests/servicestests/src/com/android/server/appop/DiscreteOpsMigrationAndRollbackTest.java b/services/tests/servicestests/src/com/android/server/appop/DiscreteOpsMigrationAndRollbackTest.java
index 8eea1c73d4f2..6c66f149baa7 100644
--- a/services/tests/servicestests/src/com/android/server/appop/DiscreteOpsMigrationAndRollbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/DiscreteOpsMigrationAndRollbackTest.java
@@ -70,7 +70,7 @@ public class DiscreteOpsMigrationAndRollbackTest {
opEvent.getDeviceId(), opEvent.getOpCode(), opEvent.getAttributionTag(),
opEvent.getOpFlags(), opEvent.getUidState(), opEvent.getAccessTime(),
opEvent.getDuration(), opEvent.getAttributionFlags(),
- (int) opEvent.getChainId(), DiscreteOpsRegistry.ACCESS_TYPE_NOTE_OP);
+ (int) opEvent.getChainId());
}
xmlRegistry.writeAndClearOldAccessHistory();
assertThat(xmlRegistry.readLargestChainIdFromDiskLocked()).isEqualTo(RECORD_COUNT);
@@ -104,7 +104,7 @@ public class DiscreteOpsMigrationAndRollbackTest {
opEvent.getDeviceId(), opEvent.getOpCode(), opEvent.getAttributionTag(),
opEvent.getOpFlags(), opEvent.getUidState(), opEvent.getAccessTime(),
opEvent.getDuration(), opEvent.getAttributionFlags(),
- (int) opEvent.getChainId(), DiscreteOpsRegistry.ACCESS_TYPE_NOTE_OP);
+ (int) opEvent.getChainId());
}
// flush records from cache to the database.
sqlRegistry.shutdown();
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
index 1de864cb4eb0..565a9b6c1c44 100644
--- a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
@@ -17,6 +17,7 @@
package com.android.server.location.contexthub;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.timeout;
@@ -42,12 +43,10 @@ import android.os.Binder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.Log;
+
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
-import java.util.Collections;
-import java.util.List;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -57,6 +56,9 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import java.util.Collections;
+import java.util.List;
+
@RunWith(AndroidJUnit4.class)
@Presubmit
public class ContextHubEndpointTest {
@@ -73,6 +75,12 @@ public class ContextHubEndpointTest {
private static final String TARGET_ENDPOINT_NAME = "Example target endpoint";
private static final int TARGET_ENDPOINT_ID = 1;
+ private static final int SAMPLE_MESSAGE_TYPE = 1234;
+ private static final HubMessage SAMPLE_MESSAGE =
+ new HubMessage.Builder(SAMPLE_MESSAGE_TYPE, new byte[] {1, 2, 3, 4, 5})
+ .setResponseRequired(true)
+ .build();
+
private ContextHubClientManager mClientManager;
private ContextHubEndpointManager mEndpointManager;
private HubInfoRegistry mHubInfoRegistry;
@@ -229,23 +237,34 @@ public class ContextHubEndpointTest {
assertThat(mTransactionManager.numReliableMessageTransactionPending()).isEqualTo(0);
}
+ @Test
+ public void testDuplicateMessageRejected() throws RemoteException {
+ IContextHubEndpoint endpoint = registerExampleEndpoint();
+ int sessionId = openTestSession(endpoint);
+
+ mEndpointManager.onMessageReceived(sessionId, SAMPLE_MESSAGE);
+ ArgumentCaptor<HubMessage> messageCaptor = ArgumentCaptor.forClass(HubMessage.class);
+ verify(mMockCallback).onMessageReceived(eq(sessionId), messageCaptor.capture());
+ assertThat(messageCaptor.getValue()).isEqualTo(SAMPLE_MESSAGE);
+
+ // Send a duplicate message and confirm it can be rejected
+ mEndpointManager.onMessageReceived(sessionId, SAMPLE_MESSAGE);
+ ArgumentCaptor<MessageDeliveryStatus> statusCaptor =
+ ArgumentCaptor.forClass(MessageDeliveryStatus.class);
+ verify(mMockEndpointCommunications)
+ .sendMessageDeliveryStatusToEndpoint(eq(sessionId), statusCaptor.capture());
+ assertThat(statusCaptor.getValue().messageSequenceNumber)
+ .isEqualTo(SAMPLE_MESSAGE.getMessageSequenceNumber());
+ assertThat(statusCaptor.getValue().errorCode).isEqualTo(ErrorCode.TRANSIENT_ERROR);
+
+ unregisterExampleEndpoint(endpoint);
+ }
+
/** A helper method to create a session and validates reliable message sending. */
private void testMessageTransactionInternal(
IContextHubEndpoint endpoint, boolean deliverMessageStatus) throws RemoteException {
- HubEndpointInfo targetInfo =
- new HubEndpointInfo(
- TARGET_ENDPOINT_NAME,
- TARGET_ENDPOINT_ID,
- ENDPOINT_PACKAGE_NAME,
- Collections.emptyList());
- int sessionId = endpoint.openSession(targetInfo, /* serviceDescriptor= */ null);
- mEndpointManager.onEndpointSessionOpenComplete(sessionId);
+ int sessionId = openTestSession(endpoint);
- final int messageType = 1234;
- HubMessage message =
- new HubMessage.Builder(messageType, new byte[] {1, 2, 3, 4, 5})
- .setResponseRequired(true)
- .build();
IContextHubTransactionCallback callback =
new IContextHubTransactionCallback.Stub() {
@Override
@@ -258,13 +277,13 @@ public class ContextHubEndpointTest {
Log.i(TAG, "Received onTransactionComplete callback, result=" + result);
}
};
- endpoint.sendMessage(sessionId, message, callback);
+ endpoint.sendMessage(sessionId, SAMPLE_MESSAGE, callback);
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(mMockEndpointCommunications, timeout(1000))
.sendMessageToEndpoint(eq(sessionId), messageCaptor.capture());
Message halMessage = messageCaptor.getValue();
- assertThat(halMessage.type).isEqualTo(message.getMessageType());
- assertThat(halMessage.content).isEqualTo(message.getMessageBody());
+ assertThat(halMessage.type).isEqualTo(SAMPLE_MESSAGE.getMessageType());
+ assertThat(halMessage.content).isEqualTo(SAMPLE_MESSAGE.getMessageBody());
assertThat(mTransactionManager.numReliableMessageTransactionPending()).isEqualTo(1);
if (deliverMessageStatus) {
@@ -308,4 +327,16 @@ public class ContextHubEndpointTest {
.isEqualTo(expectedInfo.getIdentifier().getHub());
assertThat(mEndpointManager.getNumRegisteredClients()).isEqualTo(0);
}
+
+ private int openTestSession(IContextHubEndpoint endpoint) throws RemoteException {
+ HubEndpointInfo targetInfo =
+ new HubEndpointInfo(
+ TARGET_ENDPOINT_NAME,
+ TARGET_ENDPOINT_ID,
+ ENDPOINT_PACKAGE_NAME,
+ Collections.emptyList());
+ int sessionId = endpoint.openSession(targetInfo, /* serviceDescriptor= */ null);
+ mEndpointManager.onEndpointSessionOpenComplete(sessionId);
+ return sessionId;
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 4eac1d126202..a9759c8a61f3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -102,7 +102,9 @@ import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@SmallTest
@SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the class.
@@ -4443,4 +4445,97 @@ public class GroupHelperTest extends UiServiceTestCase {
verify(mCallback).sendAppProvidedSummaryDeleteIntent(eq(pkg),
eq(deleteIntentofFirstSummary));
}
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testGroupSummaryAdded_hadUngroupedNotif_doesNotAutogroup() {
+ // Scenario:
+ // * child notification posted before summary; added to ungrouped notifications
+ // * summary posted, so now the child has a group summary and is no longer "ungrouped
+ // * another ungrouped notification is posted
+ // Confirm that the first notification (that now has a summary) is not autogrouped.
+
+ // Bookkeeping items
+ List<NotificationRecord> notifList = new ArrayList<>();
+ Map<String, NotificationRecord> summaryByGroupKey = new HashMap<>();
+
+ // Setup: post AUTOGROUP_AT_COUNT - 2 notifications so that the next notification would not
+ // trigger autogrouping, but the one after that would
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
+ NotificationRecord child = getNotificationRecord(mPkg, i, "", mUser, "group" + i, false,
+ IMPORTANCE_DEFAULT);
+ notifList.add(child);
+ mGroupHelper.onNotificationPostedWithDelay(child, notifList, summaryByGroupKey);
+ }
+
+ // Group child: posted enough before its associated summary to be put in the "ungrouped"
+ // set of notifications
+ NotificationRecord groupChild = getNotificationRecord(mPkg, AUTOGROUP_AT_COUNT - 2, "",
+ mUser, "specialGroup", false, IMPORTANCE_DEFAULT);
+ notifList.add(groupChild);
+ mGroupHelper.onNotificationPostedWithDelay(groupChild, notifList, summaryByGroupKey);
+
+ // Group summary: posted after child 1
+ NotificationRecord groupSummary = getNotificationRecord(mPkg, AUTOGROUP_AT_COUNT - 1, "",
+ mUser, "specialGroup", true, IMPORTANCE_DEFAULT);
+ notifList.add(groupSummary);
+ summaryByGroupKey.put(groupSummary.getSbn().getGroupKey(), groupSummary);
+ mGroupHelper.onGroupSummaryAdded(groupSummary, notifList);
+ mGroupHelper.onNotificationPostedWithDelay(groupSummary, notifList, summaryByGroupKey);
+
+ // One more notification posted to the group; because its summary already exists, it should
+ // never be counted as an "ungrouped" notification
+ NotificationRecord groupChild2 = getNotificationRecord(mPkg, AUTOGROUP_AT_COUNT, "",
+ mUser, "specialGroup", false, IMPORTANCE_DEFAULT);
+ notifList.add(groupChild2);
+ mGroupHelper.onNotificationPostedWithDelay(groupChild2, notifList, summaryByGroupKey);
+
+ // Now one more ungrouped notification; this would have put the number of "ungrouped"
+ // notifications above the limit if the first groupChild notification were left ungrouped
+ NotificationRecord extra = getNotificationRecord(mPkg, AUTOGROUP_AT_COUNT + 1, "", mUser,
+ "yetAnotherGroup", false, IMPORTANCE_DEFAULT);
+ notifList.add(extra);
+ mGroupHelper.onNotificationPostedWithDelay(extra, notifList, summaryByGroupKey);
+
+ // no autogrouping should have occurred
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testGroupSummaryAdded_onlyUnrelatedGroupedNotifs() {
+ // If all of the existing ungrouped notifications have nothing to do with the summary
+ // they should still get grouped as needed.
+ List<NotificationRecord> notifList = new ArrayList<>();
+ Map<String, NotificationRecord> summaryByGroupKey = new HashMap<>();
+
+ // Post 1 fewer than the autogroupable notifications, each associated with a different
+ // group without a summary.
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord child = getNotificationRecord(mPkg, i, "", mUser, "group" + i, false,
+ IMPORTANCE_DEFAULT);
+ notifList.add(child);
+ mGroupHelper.onNotificationPostedWithDelay(child, notifList, summaryByGroupKey);
+ }
+
+ // At this point we do not yet expect autogrouping.
+ // Add a group summary that is a summary associated with none of the above notifications.
+ // Because this gets considered a "summary without children", all of these notifications
+ // should now be autogrouped.
+ NotificationRecord summary = getNotificationRecord(mPkg, AUTOGROUP_AT_COUNT, "", mUser,
+ "summaryGroup", true, IMPORTANCE_DEFAULT);
+ notifList.add(summary);
+ summaryByGroupKey.put(summary.getSbn().getKey(), summary);
+ mGroupHelper.onGroupSummaryAdded(summary, notifList);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notifList, summaryByGroupKey);
+
+ // all of the above posted notifications should be autogrouped
+ String expectedGroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(mPkg, 0, String.valueOf(0), mUser));
+ verify(mCallback, times(1)).addAutoGroupSummary(
+ anyInt(), eq(mPkg), anyString(), eq(expectedGroupKey),
+ anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), anyBoolean());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index 6d8a48799112..3ca019728c2b 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -150,8 +150,6 @@ public class KeyGestureEventTests extends ShortcutKeyTestBase {
{"Meta + Left arrow -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DPAD_LEFT},
KeyGestureEvent.KEY_GESTURE_TYPE_BACK, KeyEvent.KEYCODE_DPAD_LEFT,
META_ON},
- {"Meta + Del -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DEL},
- KeyGestureEvent.KEY_GESTURE_TYPE_BACK, KeyEvent.KEYCODE_DEL, META_ON},
{"APP_SWITCH key -> Open App switcher", new int[]{KeyEvent.KEYCODE_APP_SWITCH},
KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH,
KeyEvent.KEYCODE_APP_SWITCH, 0},
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
index 948371f74a9c..ad706e879b72 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -63,11 +63,23 @@ public class ActivitySnapshotControllerTests extends TaskSnapshotPersisterTestBa
super(0.8f /* highResScale */, 0.5f /* lowResScale */);
}
+ private class TestActivitySnapshotController extends ActivitySnapshotController {
+ TestActivitySnapshotController(WindowManagerService service,
+ SnapshotPersistQueue persistQueue) {
+ super(service, persistQueue);
+ }
+ @Override
+ BaseAppSnapshotPersister.PersistInfoProvider createPersistInfoProvider(
+ WindowManagerService service) {
+ return mPersister.mPersistInfoProvider;
+ }
+ }
@Override
@Before
public void setUp() {
super.setUp();
- mActivitySnapshotController = new ActivitySnapshotController(mWm, mSnapshotPersistQueue);
+ mActivitySnapshotController = new TestActivitySnapshotController(
+ mWm, mSnapshotPersistQueue);
spyOn(mActivitySnapshotController);
doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
mActivitySnapshotController.resetTmpFields();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index d016e735f0c7..8fe08553db95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -251,10 +251,6 @@ class AppCompatActivityRobot {
doReturn(mTaskStack.top()).when(mActivityStack.top()).getOrganizedTask();
}
- void setIsInLetterboxAnimation(boolean inAnimation) {
- doReturn(inAnimation).when(mActivityStack.top()).isInLetterboxAnimation();
- }
-
void setTopTaskInMultiWindowMode(boolean inMultiWindowMode) {
doReturn(inMultiWindowMode).when(mTaskStack.top()).inMultiWindowMode();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
index d38f3b09c4fa..7bcf4eaa7c8b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
@@ -66,7 +66,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
runTestScenario((robot) -> {
robot.configureWindowStateWithTaskBar(/* hasTaskBarInsetsRoundedCorners */ true);
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -87,7 +86,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
runTestScenario((robot) -> {
robot.configureWindowStateWithTaskBar(/* hasTaskBarInsetsRoundedCorners */ false);
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -109,7 +107,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
runTestScenario((robot) -> {
robot.configureWindowStateWithTaskBar(/* hasTaskBarInsetsRoundedCorners */ true);
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -131,7 +128,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
runTestScenario((robot) -> {
robot.configureWindowStateWithTaskBar(/* hasTaskBarInsetsRoundedCorners */ true);
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -157,7 +153,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
robot.conf().setLetterboxActivityCornersRadius(-1);
robot.configureWindowState();
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -184,25 +179,17 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
robot.conf().setLetterboxActivityCornersRadius(15);
robot.configureWindowState();
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
robot.resources().configureGetDimensionPixelSize(R.dimen.taskbar_frame_height, 20);
robot.setInvCompatState(/* scale */ 0.5f);
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ true);
- robot.checkWindowStateRoundedCornersRadius(/* expected */ 7);
-
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.checkWindowStateRoundedCornersRadius(/* expected */ 7);
robot.activity().setTopActivityVisibleRequested(/* isVisibleRequested */ false);
robot.activity().setTopActivityVisible(/* isVisible */ false);
robot.checkWindowStateRoundedCornersRadius(/* expected */ 0);
-
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ true);
- robot.checkWindowStateRoundedCornersRadius(/* expected */ 7);
});
}
@@ -212,7 +199,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
robot.conf().setLetterboxActivityCornersRadius(15);
robot.configureWindowState();
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -236,7 +222,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
robot.conf().setLetterboxActivityCornersRadius(15);
robot.configureWindowState();
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -260,7 +245,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
robot.conf().setLetterboxActivityCornersRadius(15);
robot.configureWindowState();
robot.activity().createActivityWithComponent();
- robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
robot.activity().setTopActivityVisible(/* isVisible */ true);
robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
@@ -362,10 +346,6 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
mWindowState.mInvGlobalScale = scale;
}
- void setTopActivityInLetterboxAnimation(boolean inLetterboxAnimation) {
- doReturn(inLetterboxAnimation).when(activity().top()).isInLetterboxAnimation();
- }
-
void setTopActivityTransparentPolicyRunning(boolean running) {
doReturn(running).when(getTransparentPolicy()).isRunning();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxUtilsTest.java
index a4a63d266725..ac707d23b492 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxUtilsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxUtilsTest.java
@@ -63,25 +63,10 @@ public class AppCompatLetterboxUtilsTest extends WindowTestsBase {
}
@Test
- public void positionIsFromTaskWhenLetterboxAnimationIsRunning() {
+ public void positionIsFromActivity() {
runTestScenario((robot) -> {
robot.activity().createActivityWithComponent();
robot.setTopActivityLetterboxPolicyRunning(true);
- robot.activity().setIsInLetterboxAnimation(true);
- robot.activity().configureTaskBounds(
- new Rect(/* left */ 100, /* top */ 200, /* right */ 300, /* bottom */ 400));
- robot.getLetterboxPosition();
-
- robot.assertPosition(/* x */ 100, /* y */ 200);
- });
- }
-
- @Test
- public void positionIsFromActivityWhenLetterboxAnimationIsNotRunning() {
- runTestScenario((robot) -> {
- robot.activity().createActivityWithComponent();
- robot.setTopActivityLetterboxPolicyRunning(true);
- robot.activity().setIsInLetterboxAnimation(false);
robot.activity().configureTopActivityBounds(
new Rect(/* left */ 200, /* top */ 400, /* right */ 300, /* bottom */ 400));
robot.getLetterboxPosition();
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index e08197155f03..bdee3c323549 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -225,10 +225,10 @@ public class BackNavigationControllerTests extends WindowTestsBase {
CrossActivityTestCase testCase = createTopTaskWithTwoActivities();
IOnBackInvokedCallback callback = withSystemCallback(testCase.task);
testCase.windowFront.mAttrs.windowAnimations = 0x10;
- spyOn(mDisplayContent.mAppTransition.mTransitionAnimation);
- doReturn(0xffff00AB).when(mDisplayContent.mAppTransition.mTransitionAnimation)
+ spyOn(mDisplayContent.mTransitionAnimation);
+ doReturn(0xffff00AB).when(mDisplayContent.mTransitionAnimation)
.getAnimationResId(any(), anyInt(), anyInt());
- doReturn(0xffff00CD).when(mDisplayContent.mAppTransition.mTransitionAnimation)
+ doReturn(0xffff00CD).when(mDisplayContent.mTransitionAnimation)
.getDefaultAnimationResId(anyInt(), anyInt());
BackNavigationInfo backNavigationInfo = startBackNavigation();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 4854f0d948b4..862158e8a0a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -362,7 +362,19 @@ public class DisplayPolicyTests extends WindowTestsBase {
@Test
public void testSwitchDecorInsets() {
- createNavBarWithProvidedInsets(mDisplayContent);
+ final WindowState win = createApplicationWindow();
+ final WindowState bar = createNavBarWithProvidedInsets(mDisplayContent);
+ bar.getFrame().set(0, mDisplayContent.mDisplayFrames.mHeight - NAV_BAR_HEIGHT,
+ mDisplayContent.mDisplayFrames.mWidth, mDisplayContent.mDisplayFrames.mHeight);
+ final int insetsId = bar.mAttrs.providedInsets[0].getId();
+ final InsetsSourceProvider provider = mDisplayContent.getInsetsStateController()
+ .getOrCreateSourceProvider(insetsId, bar.mAttrs.providedInsets[0].getType());
+ provider.setServerVisible(true);
+ provider.updateSourceFrame(bar.getFrame());
+
+ final InsetsState prevInsetsState = new InsetsState();
+ prevInsetsState.addSource(new InsetsSource(provider.getSource()));
+
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
final DisplayInfo info = mDisplayContent.getDisplayInfo();
final int w = info.logicalWidth;
@@ -385,6 +397,18 @@ public class DisplayPolicyTests extends WindowTestsBase {
// The current insets are restored from cache directly.
assertEquals(prevConfigFrame, displayPolicy.getDecorInsetsInfo(info.rotation,
info.logicalWidth, info.logicalHeight).mConfigFrame);
+ // Assume that the InsetsSource in current InsetsState is not updated yet. And it will be
+ // replaced by the one in cache.
+ InsetsState currentInsetsState = new InsetsState();
+ final InsetsSource prevSource = new InsetsSource(provider.getSource());
+ prevSource.getFrame().scale(0.5f);
+ currentInsetsState.addSource(prevSource);
+ currentInsetsState = mDisplayContent.getInsetsPolicy().adjustInsetsForWindow(
+ win, currentInsetsState);
+ if (com.android.window.flags.Flags.useCachedInsetsForDisplaySwitch()) {
+ assertEquals(prevInsetsState.peekSource(insetsId),
+ currentInsetsState.peekSource(insetsId));
+ }
// If screen is not fully turned on, then the cache should be preserved.
displayPolicy.screenTurnedOff(false /* acquireSleepToken */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java
index 51e02405e489..8ee5999e7c24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java
@@ -38,7 +38,6 @@ import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.InputWindowHandle;
-import android.view.SurfaceControl;
import android.view.WindowManager;
import com.android.server.testutils.StubTransaction;
@@ -76,8 +75,7 @@ public class LetterboxAttachInputTest extends WindowTestsBase {
doReturn(0.5f).when(letterboxOverrides).getLetterboxWallpaperDarkScrimAlpha();
mWindowState = createWindowState();
mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
- mock(AppCompatReachabilityPolicy.class), letterboxOverrides,
- () -> mock(SurfaceControl.class));
+ mock(AppCompatReachabilityPolicy.class), letterboxOverrides);
mTransaction = spy(StubTransaction.class);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index a51a44f6167b..e5533b659e03 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -68,7 +68,6 @@ public class LetterboxTest {
private SurfaceControlMocker mSurfaces;
private SurfaceControl.Transaction mTransaction;
- private SurfaceControl mParentSurface = mock(SurfaceControl.class);
private AppCompatLetterboxOverrides mLetterboxOverrides;
private WindowState mWindowState;
@@ -84,7 +83,7 @@ public class LetterboxTest {
doReturn(0.5f).when(mLetterboxOverrides).getLetterboxWallpaperDarkScrimAlpha();
mWindowState = mock(WindowState.class);
mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
- mock(AppCompatReachabilityPolicy.class), mLetterboxOverrides, () -> mParentSurface);
+ mock(AppCompatReachabilityPolicy.class), mLetterboxOverrides);
mTransaction = spy(StubTransaction.class);
}
@@ -259,22 +258,6 @@ public class LetterboxTest {
}
@Test
- public void testNeedsApplySurfaceChanges_setParentSurface() {
- mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
- applySurfaceChanges();
-
- verify(mTransaction).reparent(mSurfaces.top, mParentSurface);
- assertFalse(mLetterbox.needsApplySurfaceChanges());
-
- mParentSurface = mock(SurfaceControl.class);
-
- assertTrue(mLetterbox.needsApplySurfaceChanges());
-
- applySurfaceChanges();
- verify(mTransaction).reparent(mSurfaces.top, mParentSurface);
- }
-
- @Test
public void testApplySurfaceChanges_cornersNotRounded_surfaceFullWindowSurfaceNotCreated() {
mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
applySurfaceChanges();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index e4a1bf603cf0..34e9bed8463a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -31,6 +31,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;
import static com.android.server.wm.ActivityRecord.State.FINISHING;
import static com.android.server.wm.ActivityRecord.State.PAUSED;
import static com.android.server.wm.ActivityRecord.State.PAUSING;
@@ -82,6 +83,7 @@ import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
+import android.view.DisplayInfo;
import androidx.test.filters.MediumTest;
@@ -1379,6 +1381,23 @@ public class RootWindowContainerTests extends WindowTestsBase {
verify(controller, never()).notifyTaskProfileLocked(any(), anyInt());
}
+ @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+ @Test
+ public void testOnDisplayBelongToTopologyChanged() {
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.copyFrom(mDisplayInfo);
+ displayInfo.displayId = DEFAULT_DISPLAY + 1;
+ final DisplayContent dc = createNewDisplay(displayInfo);
+ final int displayId = dc.getDisplayId();
+
+ doReturn(dc).when(mRootWindowContainer).getDisplayContentOrCreate(displayId);
+ doReturn(true).when(mWm.mDisplayWindowSettings).shouldShowSystemDecorsLocked(dc);
+
+ mRootWindowContainer.onDisplayAdded(displayId);
+ verify(mWm.mDisplayManagerInternal, times(1)).onDisplayBelongToTopologyChanged(anyInt(),
+ anyBoolean());
+ }
+
/**
* Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
* info for test cases.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
index 51ea498811fc..f22ecb5eb3f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
@@ -68,11 +68,8 @@ public class TaskSnapshotLowResDisabledTest extends TaskSnapshotPersisterTestBas
public void testPersistAndLoadSnapshot() {
mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] files = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg")};
- final File[] nonExistsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg")};
+ final File[] files = convertFilePath("1.proto", "1.jpg");
+ final File[] nonExistsFiles = convertFilePath("1_reduced.proto");
assertTrueForFiles(files, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* isLowResolution */);
@@ -92,14 +89,9 @@ public class TaskSnapshotLowResDisabledTest extends TaskSnapshotPersisterTestBas
taskIds.add(1);
mPersister.removeObsoleteFiles(taskIds, new int[]{mTestUserId});
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] existsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg")};
- final File[] nonExistsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/2.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
+ final File[] existsFiles = convertFilePath("1.proto", "1.jpg");
+ final File[] nonExistsFiles = convertFilePath("1_reduced.proto", "2.proto", "2.jpg",
+ "2_reduced.jpg");
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
@@ -112,14 +104,8 @@ public class TaskSnapshotLowResDisabledTest extends TaskSnapshotPersisterTestBas
mPersister.removeObsoleteFiles(taskIds, new int[]{mTestUserId});
mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] existsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/2.jpg")};
- final File[] nonExistsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
+ final File[] existsFiles = convertFilePath("1.proto", "1.jpg", "2.proto", "2.jpg");
+ final File[] nonExistsFiles = convertFilePath("1_reduced.jpg", "2_reduced.jpg");
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 4b54e4464ca7..af06c14516a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -75,9 +75,7 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
public void testPersistAndLoadSnapshot() {
mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] files = new File[]{new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg")};
+ final File[] files = convertFilePath("1.proto", "1.jpg", "1_reduced.jpg");
assertTrueForFiles(files, File::exists, " must exist");
final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* isLowResolution */);
assertNotNull(snapshot);
@@ -140,13 +138,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
mSnapshotPersistQueue.waitForQueueEmpty();
// Make sure 1,2 were purged but removeObsoleteFiles wasn't.
- final File[] existsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/3.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/4.proto")};
- final File[] nonExistsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/100.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.proto")};
+ final File[] existsFiles = convertFilePath("3.proto", "4.proto");
+ final File[] nonExistsFiles = convertFilePath("100.proto", "1.proto", "2.proto");
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
@@ -427,14 +420,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
taskIds.add(1);
mPersister.removeObsoleteFiles(taskIds, new int[]{mTestUserId});
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] existsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg")};
- final File[] nonExistsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/2.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
+ final File[] existsFiles = convertFilePath("1.proto", "1.jpg", "1_reduced.jpg");
+ final File[] nonExistsFiles = convertFilePath("2.proto", "2.jpg", "2_reduced.jpg");
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
@@ -447,13 +434,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
mPersister.removeObsoleteFiles(taskIds, new int[]{mTestUserId});
mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
mSnapshotPersistQueue.waitForQueueEmpty();
- final File[] existsFiles = new File[]{
- new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
- new File(FILES_DIR.getPath() + "/snapshots/2.jpg"),
- new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
+ final File[] existsFiles = convertFilePath("1.proto", "1.jpg", "1_reduced.jpg", "2.proto",
+ "2.jpg", "2_reduced.jpg");
assertTrueForFiles(existsFiles, File::exists, " must exist");
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 1e16c97de647..b2c195e8ebaa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.ContextWrapper;
import android.content.res.Resources;
@@ -46,6 +47,7 @@ import android.window.TaskSnapshot;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
+import com.android.window.flags.Flags;
import org.junit.After;
import org.junit.AfterClass;
@@ -129,12 +131,33 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
return;
}
for (File file : files) {
- if (!file.isDirectory()) {
- file.delete();
+ if (file.isDirectory()) {
+ final File[] subFiles = file.listFiles();
+ if (subFiles == null) {
+ continue;
+ }
+ for (File subFile : subFiles) {
+ subFile.delete();
+ }
}
+ file.delete();
}
}
+ File[] convertFilePath(@NonNull String... fileNames) {
+ final File[] files = new File[fileNames.length];
+ final String path;
+ if (Flags.scrambleSnapshotFileName()) {
+ path = mPersister.mPersistInfoProvider.getDirectory(mTestUserId).getPath();
+ } else {
+ path = FILES_DIR.getPath() + "/snapshots/";
+ }
+ for (int i = 0; i < fileNames.length; i++) {
+ files[i] = new File(path + fileNames[i]);
+ }
+ return files;
+ }
+
TaskSnapshot createSnapshot() {
return new TaskSnapshotBuilder().setTopActivityComponent(getUniqueComponentName()).build();
}
diff --git a/services/usb/java/com/android/server/usb/UsbManagerInternal.java b/services/usb/java/com/android/server/usb/UsbManagerInternal.java
deleted file mode 100644
index 31c5986c45b8..000000000000
--- a/services/usb/java/com/android/server/usb/UsbManagerInternal.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.usb;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.hardware.usb.IUsbOperationInternal;
-import android.hardware.usb.UsbPort;
-import android.util.ArraySet;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * UsbManagerInternal provides internal APIs for the UsbService to
- * reduce IPC overhead costs and support internal USB data signal stakers.
- *
- * @hide Only for use within the system server.
- */
-public abstract class UsbManagerInternal {
-
- public static final int OS_USB_DISABLE_REASON_AAPM = 0;
- public static final int OS_USB_DISABLE_REASON_LOCKDOWN_MODE = 1;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {OS_USB_DISABLE_REASON_AAPM,
- OS_USB_DISABLE_REASON_LOCKDOWN_MODE})
- public @interface OsUsbDisableReason {
- }
-
- public abstract boolean enableUsbData(String portId, boolean enable,
- int operationId, IUsbOperationInternal callback, @OsUsbDisableReason int disableReason);
-
- public abstract UsbPort[] getPorts();
-
-} \ No newline at end of file
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 4395b76d91cc..7808b2e318b2 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -27,7 +27,10 @@ import static android.hardware.usb.UsbPortStatus.MODE_UFP;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
+import android.hardware.usb.IUsbManagerInternal;
+
import android.annotation.NonNull;
+import android.annotation.IntDef;
import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
@@ -80,12 +83,16 @@ import dalvik.annotation.optimization.NeverCompile;
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* UsbService manages all USB related state, including both host and device support.
* Host related events and calls are delegated to UsbHostManager, and device related
@@ -93,6 +100,15 @@ import java.util.concurrent.CompletableFuture;
*/
public class UsbService extends IUsbManager.Stub {
+ public static final int OS_USB_DISABLE_REASON_AAPM = 0;
+ public static final int OS_USB_DISABLE_REASON_LOCKDOWN_MODE = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {OS_USB_DISABLE_REASON_AAPM,
+ OS_USB_DISABLE_REASON_LOCKDOWN_MODE})
+ public @interface OsUsbDisableReason {
+ }
+
public static class Lifecycle extends SystemService {
private UsbService mUsbService;
private final CompletableFuture<Void> mOnStartFinished = new CompletableFuture<>();
@@ -227,7 +243,7 @@ public class UsbService extends IUsbManager.Stub {
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, null);
if(android.hardware.usb.flags.Flags.enableUsbDataSignalStakingInternal()) {
- LocalServices.addService(UsbManagerInternal.class, new UsbManagerInternalImpl());
+ LocalServices.addService(IUsbManagerInternal.class, new UsbManagerInternalImpl());
}
}
@@ -246,7 +262,7 @@ public class UsbService extends IUsbManager.Stub {
mPermissionManager = new UsbPermissionManager(context, this);
if(android.hardware.usb.flags.Flags.enableUsbDataSignalStakingInternal()) {
- LocalServices.addService(UsbManagerInternal.class, new UsbManagerInternalImpl());
+ LocalServices.addService(IUsbManagerInternal.class, new UsbManagerInternalImpl());
}
}
@@ -1536,24 +1552,30 @@ public class UsbService extends IUsbManager.Stub {
enableUsbDataInternal(port.getId(), !lockDownTriggeredByUser,
STRONG_AUTH_OPERATION_ID,
new IUsbOperationInternal.Default(),
- UsbManagerInternal.OS_USB_DISABLE_REASON_LOCKDOWN_MODE,
+ OS_USB_DISABLE_REASON_LOCKDOWN_MODE,
true);
}
}
}
- private class UsbManagerInternalImpl extends UsbManagerInternal {
- @Override
- public boolean enableUsbData(String portId, boolean enable,
- int operationId, IUsbOperationInternal callback,
- @OsUsbDisableReason int disableReason) {
- return enableUsbDataInternal(portId, enable, operationId, callback,
- disableReason, true);
- }
+ private class UsbManagerInternalImpl extends IUsbManagerInternal.Stub {
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
@Override
- public UsbPort[] getPorts() {
- return mPortManager.getPorts();
+ public boolean enableUsbDataSignal(boolean enable,
+ @OsUsbDisableReason int disableReason) {
+ boolean result = true;
+ int operationId = sUsbOperationCount.incrementAndGet() + disableReason;
+ for (UsbPort port : mPortManager.getPorts()) {
+ boolean success = enableUsbDataInternal(port.getId(), enable, operationId,
+ new IUsbOperationInternal.Default(), disableReason, true);
+ if(!success) {
+ Slog.e(TAG, "enableUsbDataInternal failed to change USB port "
+ + port.getId() + "state to " + enable);
+ }
+ result &= success;
+ }
+ return result;
}
}
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 531f51604507..9e57fd3c1a7b 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -30,6 +30,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
import com.android.internal.telecom.IVideoProvider;
import com.android.server.telecom.flags.Flags;
@@ -680,6 +681,7 @@ public final class Call {
private final @CallDirection int mCallDirection;
private final @Connection.VerificationStatus int mCallerNumberVerificationStatus;
private final Uri mContactPhotoUri;
+ private final UserHandle mAssociatedUser;
/**
* Whether the supplied capabilities supports the specified capability.
@@ -1081,6 +1083,16 @@ public final class Call {
return mCallerNumberVerificationStatus;
}
+ /**
+ * Gets the user that originated the call
+ * @return The user
+ *
+ * @hide
+ */
+ public UserHandle getAssociatedUser() {
+ return mAssociatedUser;
+ }
+
@Override
public boolean equals(Object o) {
if (o instanceof Details) {
@@ -1107,7 +1119,8 @@ public final class Call {
Objects.equals(mCallDirection, d.mCallDirection) &&
Objects.equals(mCallerNumberVerificationStatus,
d.mCallerNumberVerificationStatus) &&
- Objects.equals(mContactPhotoUri, d.mContactPhotoUri);
+ Objects.equals(mContactPhotoUri, d.mContactPhotoUri) &&
+ Objects.equals(mAssociatedUser, d.mAssociatedUser);
}
return false;
}
@@ -1133,7 +1146,8 @@ public final class Call {
mContactDisplayName,
mCallDirection,
mCallerNumberVerificationStatus,
- mContactPhotoUri);
+ mContactPhotoUri,
+ mAssociatedUser);
}
/** {@hide} */
@@ -1158,7 +1172,8 @@ public final class Call {
String contactDisplayName,
int callDirection,
int callerNumberVerificationStatus,
- Uri contactPhotoUri) {
+ Uri contactPhotoUri,
+ UserHandle originatingUser) {
mState = state;
mTelecomCallId = telecomCallId;
mHandle = handle;
@@ -1180,6 +1195,7 @@ public final class Call {
mCallDirection = callDirection;
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
mContactPhotoUri = contactPhotoUri;
+ mAssociatedUser = originatingUser;
}
/** {@hide} */
@@ -1205,7 +1221,8 @@ public final class Call {
parcelableCall.getContactDisplayName(),
parcelableCall.getCallDirection(),
parcelableCall.getCallerNumberVerificationStatus(),
- parcelableCall.getContactPhotoUri()
+ parcelableCall.getContactPhotoUri(),
+ parcelableCall.getAssociatedUser()
);
}
@@ -2631,7 +2648,8 @@ public final class Call {
mDetails.getContactDisplayName(),
mDetails.getCallDirection(),
mDetails.getCallerNumberVerificationStatus(),
- mDetails.getContactPhotoUri()
+ mDetails.getContactPhotoUri(),
+ mDetails.getAssociatedUser()
);
fireDetailsChanged(mDetails);
}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 6a1318982e77..bd004e5e6231 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -16,14 +16,17 @@
package android.telecom;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.telecom.Call.Details.CallDirection;
import com.android.internal.telecom.IVideoProvider;
@@ -70,6 +73,7 @@ public final class ParcelableCall implements Parcelable {
private String mContactDisplayName;
private String mActiveChildCallId;
private Uri mContactPhotoUri;
+ private UserHandle mAssociatedUser;
public ParcelableCallBuilder setId(String id) {
mId = id;
@@ -230,6 +234,11 @@ public final class ParcelableCall implements Parcelable {
return this;
}
+ public ParcelableCallBuilder setAssociatedUser(UserHandle user) {
+ mAssociatedUser = user;
+ return this;
+ }
+
public ParcelableCall createParcelableCall() {
return new ParcelableCall(
mId,
@@ -262,7 +271,8 @@ public final class ParcelableCall implements Parcelable {
mCallerNumberVerificationStatus,
mContactDisplayName,
mActiveChildCallId,
- mContactPhotoUri);
+ mContactPhotoUri,
+ mAssociatedUser);
}
public static ParcelableCallBuilder fromParcelableCall(ParcelableCall parcelableCall) {
@@ -300,6 +310,7 @@ public final class ParcelableCall implements Parcelable {
newBuilder.mContactDisplayName = parcelableCall.mContactDisplayName;
newBuilder.mActiveChildCallId = parcelableCall.mActiveChildCallId;
newBuilder.mContactPhotoUri = parcelableCall.mContactPhotoUri;
+ newBuilder.mAssociatedUser = parcelableCall.mAssociatedUser;
return newBuilder;
}
}
@@ -336,6 +347,7 @@ public final class ParcelableCall implements Parcelable {
private final String mContactDisplayName;
private final String mActiveChildCallId; // Only valid for CDMA conferences
private final Uri mContactPhotoUri;
+ private final UserHandle mAssociatedUser;
public ParcelableCall(
String id,
@@ -368,7 +380,8 @@ public final class ParcelableCall implements Parcelable {
int callerNumberVerificationStatus,
String contactDisplayName,
String activeChildCallId,
- Uri contactPhotoUri
+ Uri contactPhotoUri,
+ UserHandle associatedUser
) {
mId = id;
mState = state;
@@ -401,6 +414,7 @@ public final class ParcelableCall implements Parcelable {
mContactDisplayName = contactDisplayName;
mActiveChildCallId = activeChildCallId;
mContactPhotoUri = contactPhotoUri;
+ mAssociatedUser = associatedUser;
}
/** The unique ID of the call. */
@@ -624,6 +638,13 @@ public final class ParcelableCall implements Parcelable {
return mContactPhotoUri;
}
+ /**
+ * @return the originating user
+ */
+ public @NonNull UserHandle getAssociatedUser() {
+ return mAssociatedUser;
+ }
+
/**
* @return On a CDMA conference with two participants, returns the ID of the child call that's
@@ -666,6 +687,9 @@ public final class ParcelableCall implements Parcelable {
source.readList(conferenceableCallIds, classLoader, java.lang.String.class);
Bundle intentExtras = source.readBundle(classLoader);
Bundle extras = source.readBundle(classLoader);
+ if (extras == null) {
+ extras = new Bundle();
+ }
int supportedAudioRoutes = source.readInt();
boolean isRttCallChanged = source.readByte() == 1;
ParcelableRttCall rttCall = source.readParcelable(classLoader, android.telecom.ParcelableRttCall.class);
@@ -675,6 +699,8 @@ public final class ParcelableCall implements Parcelable {
String contactDisplayName = source.readString();
String activeChildCallId = source.readString();
Uri contactPhotoUri = source.readParcelable(classLoader, Uri.class);
+ UserHandle associatedUser = source.readParcelable(classLoader, UserHandle.class);
+ extras.putParcelable(Intent.EXTRA_USER_HANDLE, associatedUser);
return new ParcelableCallBuilder()
.setId(id)
.setState(state)
@@ -707,6 +733,7 @@ public final class ParcelableCall implements Parcelable {
.setContactDisplayName(contactDisplayName)
.setActiveChildCallId(activeChildCallId)
.setContactPhotoUri(contactPhotoUri)
+ .setAssociatedUser(associatedUser)
.createParcelableCall();
}
@@ -757,6 +784,7 @@ public final class ParcelableCall implements Parcelable {
destination.writeString(mContactDisplayName);
destination.writeString(mActiveChildCallId);
destination.writeParcelable(mContactPhotoUri, 0);
+ destination.writeParcelable(mAssociatedUser, 0);
}
@Override
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 58833e8f8141..50c5a6b68c7b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -10962,7 +10962,7 @@ public class CarrierConfigManager {
sDefaults.putInt(KEY_MMS_SMS_TO_MMS_TEXT_THRESHOLD_INT, -1);
sDefaults.putInt(KEY_MMS_SUBJECT_MAX_LENGTH_INT, 40);
sDefaults.putInt(KEY_MMS_NETWORK_RELEASE_TIMEOUT_MILLIS_INT, 5 * 1000);
- sDefaults.putInt(KEY_MMS_MAX_NTN_PAYLOAD_SIZE_BYTES_INT, 3 * 1000);
+ sDefaults.putInt(KEY_MMS_MAX_NTN_PAYLOAD_SIZE_BYTES_INT, -1);
sDefaults.putString(KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, "");
sDefaults.putString(KEY_MMS_HTTP_PARAMS_STRING, "");
sDefaults.putString(KEY_MMS_NAI_SUFFIX_STRING, "");
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d2741ac7ee9f..e04d285d6632 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1187,6 +1187,61 @@ public class SubscriptionManager {
public static final String IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM =
SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM;
+ /**
+ * TelephonyProvider column name for satellite entitlement barred plmns. The value of this
+ * column is set based on entitlement query result for satellite configuration.
+ * By default, it's empty.
+ * <P>Type: TEXT </P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ENTITLEMENT_BARRED_PLMNS =
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_BARRED_PLMNS;
+
+ /**
+ * TelephonyProvider column name for satellite entitlement data plan for plmns. The value
+ * of this column is set based on entitlement query result for satellite configuration.
+ * By default, it's empty.
+ * <P>Type: TEXT </P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS =
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS;
+
+ /**
+ * TelephonyProvider column name for satellite entitlement service type map. The value of
+ * this column is set based on entitlement query result for satellite configuration.
+ * By default, it's empty.
+ * <P>Type: TEXT </P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP =
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP;
+
+ /**
+ * TelephonyProvider column name for satellite entitlement data service policy. The value
+ * of this column is set based on entitlement query result for satellite configuration.
+ * By default, it's empty.
+ * <P>Type: TEXT </P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY =
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY;
+
+ /**
+ * TelephonyProvider column name for satellite entitlement voice service policy. The value
+ * of this column is set based on entitlement query result for satellite configuration.
+ * By default, it's empty.
+ * <P>Type: TEXT </P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY =
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"USAGE_SETTING_"},
diff --git a/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
index 3498974b348e..229c7bfb53e9 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
@@ -103,6 +103,10 @@ public class IntegrationTests {
@RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public void reportJankStats_confirmPendingStatsIncreases() {
Activity jankTrackerActivity = mJankTrackerActivityRule.launchActivity(null);
+ mDevice.wait(Until.findObject(
+ By.text(jankTrackerActivity.getString(R.string.continue_test))),
+ WAIT_FOR_TIMEOUT_MS);
+
EditText editText = jankTrackerActivity.findViewById(R.id.edit_text);
JankTracker jankTracker = editText.getJankTracker();
@@ -135,6 +139,10 @@ public class IntegrationTests {
public void simulateWidgetStateChanges_confirmStateChangesAreTracked() {
JankTrackerActivity jankTrackerActivity =
mJankTrackerActivityRule.launchActivity(null);
+ mDevice.wait(Until.findObject(
+ By.text(jankTrackerActivity.getString(R.string.continue_test))),
+ WAIT_FOR_TIMEOUT_MS);
+
TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
JankTracker jankTracker = testWidget.getJankTracker();
jankTracker.forceListenerRegistration();
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bottom_half_pip.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bottom_half_pip.xml
index 2f9c3aa82057..15e2a798b2cf 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bottom_half_pip.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bottom_half_pip.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/holo_blue_bright">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bubble.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bubble.xml
index 7c7b2cacaefb..4bc70996eba8 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bubble.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_bubble.xml
@@ -16,6 +16,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml
index f0dfdfce035f..e98ffd045d3d 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml
@@ -19,5 +19,6 @@
android:id="@+id/root_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical">
</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
index 939ba81a47ea..16c906d9ee42 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
<LinearLayout
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml
index 6d4de995bd73..eedb910b2b4e 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml
@@ -19,6 +19,7 @@
android:id="@+id/secondary_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical">
<Button
@@ -49,4 +50,4 @@
android:layout_height="48dp"
android:text="Enter pip" />
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_launch_new.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_launch_new.xml
index fe7bced690f9..2ab5fe7b9d6c 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_launch_new.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_launch_new.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
<Button
android:id="@+id/launch_second_activity"
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml
index 6d5a9dd29248..aeb8423680a3 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/holo_orange_light">
@@ -29,4 +30,4 @@
android:text="NonResizeableActivity"
android:textAppearance="?android:attr/textAppearanceLarge"/>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml
index 365a0ea017f6..d66b3d74e114 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/holo_blue_bright">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen.xml
index 79e88e49b99e..16c3bc07d55c 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/holo_green_light">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml
index ed9feaf1eade..7643cf5de216 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/holo_blue_light">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
index c34d2003ef42..79e7bb5de96e 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:gravity="center"
android:orientation="vertical"
android:background="@android:color/holo_orange_light">
@@ -39,4 +40,4 @@
android:gravity="center_vertical|center_horizontal"
android:text="Start Media Projection with extra intent"
android:textAppearance="?android:attr/textAppearanceLarge"/>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent.xml
index 0730ded66ce4..32df5f015414 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent.xml
@@ -15,6 +15,7 @@
~ limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent_launch.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent_launch.xml
index ff4ead95f16e..a0c87fd17fc3 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent_launch.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_transparent_launch.xml
@@ -17,6 +17,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@android:color/black">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/notification_button.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/notification_button.xml
index 78072006f681..da58b3f43c73 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/notification_button.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/notification_button.xml
@@ -18,10 +18,12 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
<Button
android:id="@+id/post_notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|center_vertical"
android:text="Post Notification" />
</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/task_button.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/task_button.xml
index 8f75d175d00a..ec3135c0a42d 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/task_button.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/task_button.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
<Button
android:id="@+id/launch_new_task"
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
index 4418b5a5ff82..30bf616cfe74 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivity.java
@@ -30,7 +30,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
-import android.view.WindowManager;
public class ImeActivity extends Activity {
@@ -64,10 +63,6 @@ public class ImeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.activity_ime);
final var filter = new IntentFilter();
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java
index 95f933f97bb2..887a15c9ea90 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java
@@ -30,8 +30,6 @@ public class ImeEditorPopupDialogActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
p.softInputMode = SOFT_INPUT_STATE_ALWAYS_HIDDEN;
getWindow().setAttributes(p);
LinearLayout layout = new LinearLayout(this);
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewActivity.java
index e5710c850f07..97d7a64d5ebf 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewActivity.java
@@ -19,17 +19,12 @@ package com.android.server.wm.flicker.testapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.view.WindowManager;
import android.widget.Button;
public class LaunchNewActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.activity_launch_new);
Button button = findViewById(R.id.launch_second_activity);
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewTaskActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewTaskActivity.java
index 1809781b33e6..402a393e7028 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewTaskActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/LaunchNewTaskActivity.java
@@ -21,17 +21,12 @@ import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.view.WindowManager;
import android.widget.Button;
public class LaunchNewTaskActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.task_button);
Button button = findViewById(R.id.launch_new_task);
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NotificationActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NotificationActivity.java
index d6427abcc65a..61254385e980 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NotificationActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NotificationActivity.java
@@ -45,14 +45,10 @@ public class NotificationActivity extends Activity {
requestPermissions(new String[] { POST_NOTIFICATIONS }, 0);
}
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.notification_button);
- Button button = findViewById(R.id.post_notification);
- button.setOnClickListener(v -> postNotification());
+ ((Button) findViewById(R.id.post_notification))
+ .setOnClickListener(v -> postNotification());
createNotificationChannel();
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
index ee25ab2fb66c..e030dcf0db9b 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
@@ -47,8 +47,6 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Rational;
import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.RadioButton;
@@ -145,12 +143,6 @@ public class PipActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final Window window = getWindow();
- final WindowManager.LayoutParams layoutParams = window.getAttributes();
- layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- window.setAttributes(layoutParams);
-
setContentView(R.layout.activity_pip);
findViewById(R.id.media_session_start)
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitOnlyActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitOnlyActivity.java
index b1876b5e5511..552d843676bb 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitOnlyActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitOnlyActivity.java
@@ -18,16 +18,11 @@ package com.android.server.wm.flicker.testapp;
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
public class PortraitOnlyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.activity_simple);
}
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
index ce7a0059fa2d..e98c34db0cd9 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
@@ -61,8 +61,6 @@ public class SeamlessRotationActivity extends Activity {
private void enableSeamlessRotation() {
WindowManager.LayoutParams p = getWindow().getAttributes();
p.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ShowWhenLockedActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ShowWhenLockedActivity.java
index 6f94b74ccf41..a533c9052574 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ShowWhenLockedActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ShowWhenLockedActivity.java
@@ -18,16 +18,11 @@ package com.android.server.wm.flicker.testapp;
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
public class ShowWhenLockedActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.activity_simple);
}
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SimpleActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SimpleActivity.java
index 699abf87d341..c56eefe32189 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SimpleActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SimpleActivity.java
@@ -18,16 +18,11 @@ package com.android.server.wm.flicker.testapp;
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
public class SimpleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WindowManager.LayoutParams p = getWindow().getAttributes();
- p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
- .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- getWindow().setAttributes(p);
setContentView(R.layout.activity_simple);
}
}
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index c666fb7e05f1..2799f6c79215 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -382,14 +382,6 @@ class KeyGestureControllerTests {
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
),
TestData(
- "META + DEL -> Back",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_DEL),
- KeyGestureEvent.KEY_GESTURE_TYPE_BACK,
- intArrayOf(KeyEvent.KEYCODE_DEL),
- KeyEvent.META_META_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
- ),
- TestData(
"META + ESC -> Back",
intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_ESCAPE),
KeyGestureEvent.KEY_GESTURE_TYPE_BACK,
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 16c6e3baf051..46cb5b7482e9 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -55,4 +55,8 @@ android_test {
"mts-crashrecovery",
],
min_sdk_version: "36",
+
+ // Test coverage system runs on different devices. Need to
+ // compile for all architecture.
+ compile_multilib: "both",
}
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
index 51d57f0a0de9..f5d4b0c5e345 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
@@ -24,15 +24,20 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.hardware.usb.IUsbManagerInternal;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.flags.Flags;
import android.hardware.usb.UsbPort;
@@ -70,7 +75,9 @@ public class UsbServiceTest {
@Mock
private IUsbOperationInternal mCallback;
- private static final String TEST_PORT_ID = "123";
+ private static final String TEST_PORT_ID = "1";
+
+ private static final String TEST_PORT_ID_2 = "2";
private static final int TEST_TRANSACTION_ID = 1;
@@ -84,7 +91,7 @@ public class UsbServiceTest {
private UsbService mUsbService;
- private UsbManagerInternal mUsbManagerInternal;
+ private IUsbManagerInternal mIUsbManagerInternal;
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -101,9 +108,9 @@ public class UsbServiceTest {
mUsbService = new UsbService(mContext, mUsbPortManager, mUsbAlsaManager,
mUserManager, mUsbSettingsManager);
- mUsbManagerInternal = LocalServices.getService(UsbManagerInternal.class);
- assertWithMessage("LocalServices.getService(UsbManagerInternal.class)")
- .that(mUsbManagerInternal).isNotNull();
+ mIUsbManagerInternal = LocalServices.getService(IUsbManagerInternal.class);
+ assertWithMessage("LocalServices.getService(IUsbManagerInternal.class)")
+ .that(mIUsbManagerInternal).isNotNull();
}
private void assertToggleUsbSuccessfully(int requester, boolean enable,
@@ -255,30 +262,42 @@ public class UsbServiceTest {
assertToggleUsbSuccessfully(TEST_INTERNAL_REQUESTER_REASON_1, true, false);
}
- /**
- * Verify USB Manager internal calls mPortManager to get UsbPorts
- */
@Test
- public void usbManagerInternal_getPorts_callsPortManager() {
- when(mUsbPortManager.getPorts()).thenReturn(new UsbPort[] {});
-
- UsbPort[] ports = mUsbManagerInternal.getPorts();
-
- verify(mUsbPortManager).getPorts();
- assertEquals(ports.length, 0);
+ public void usbManagerInternal_enableUsbDataSignal_successfullyEnabled() {
+ assertTrue(runInternalUsbDataSignalTest(true, true, true));
}
@Test
- public void usbManagerInternal_enableUsbData_successfullyEnable() {
- boolean desiredEnableState = true;
+ public void usbManagerInternal_enableUsbDataSignal_successfullyDisabled() {
+ assertTrue(runInternalUsbDataSignalTest(false, true, true));
+ }
- assertTrue(mUsbManagerInternal.enableUsbData(TEST_PORT_ID, desiredEnableState,
- TEST_TRANSACTION_ID, mCallback, TEST_INTERNAL_REQUESTER_REASON_1));
+ @Test
+ public void usbManagerInternal_enableUsbDataSignal_returnsFalseIfOnePortFails() {
+ assertFalse(runInternalUsbDataSignalTest(true, true, false));
+ }
- verify(mUsbPortManager).enableUsbData(TEST_PORT_ID,
- desiredEnableState, TEST_TRANSACTION_ID, mCallback, null);
- verifyZeroInteractions(mCallback);
- clearInvocations(mUsbPortManager);
- clearInvocations(mCallback);
+ private boolean runInternalUsbDataSignalTest(boolean desiredEnableState, boolean portOneSuccess,
+ boolean portTwoSuccess) {
+ UsbPort port = mock(UsbPort.class);
+ UsbPort port2 = mock(UsbPort.class);
+ when(port.getId()).thenReturn(TEST_PORT_ID);
+ when(port2.getId()).thenReturn(TEST_PORT_ID_2);
+ when(mUsbPortManager.getPorts()).thenReturn(new UsbPort[] { port, port2 });
+ when(mUsbPortManager.enableUsbData(eq(TEST_PORT_ID),
+ eq(desiredEnableState), anyInt(), any(IUsbOperationInternal.class), isNull()))
+ .thenReturn(portOneSuccess);
+ when(mUsbPortManager.enableUsbData(eq(TEST_PORT_ID_2),
+ eq(desiredEnableState), anyInt(), any(IUsbOperationInternal.class), isNull()))
+ .thenReturn(portTwoSuccess);
+ try {
+ boolean result = mIUsbManagerInternal.enableUsbDataSignal(desiredEnableState,
+ TEST_INTERNAL_REQUESTER_REASON_1);
+ clearInvocations(mUsbPortManager);
+ return result;
+ } catch(RemoteException e) {
+ fail("RemoteException thrown when calling enableUsbDataSignal");
+ return false;
+ }
}
}
diff --git a/tools/codegen/src/com/android/codegen/Debug.kt b/tools/codegen/src/com/android/codegen/Debug.kt
index de3184468540..6423c4f7f6c0 100644
--- a/tools/codegen/src/com/android/codegen/Debug.kt
+++ b/tools/codegen/src/com/android/codegen/Debug.kt
@@ -21,7 +21,7 @@ import com.github.javaparser.ast.Node
fun Node.dump(indent: String = ""): String {
return buildString {
append(indent)
- appendln(dumpOneLineNoChildren())
+ appendLine(dumpOneLineNoChildren())
childNodes.forEach { child ->
append(child.dump(indent + " "))
}
diff --git a/tools/codegen/src/com/android/codegen/FeatureFlag.kt b/tools/codegen/src/com/android/codegen/FeatureFlag.kt
index 24150d637a7b..f305429f516f 100644
--- a/tools/codegen/src/com/android/codegen/FeatureFlag.kt
+++ b/tools/codegen/src/com/android/codegen/FeatureFlag.kt
@@ -22,6 +22,6 @@ enum class FeatureFlag(val onByDefault: Boolean, val desc: String = "") {
CONST_DEFS(true, "@Int/StringDef's based on declared static constants"),
FOR_EACH_FIELD(false, "forEachField((name, value) -> ...)");
- val kebabCase = name.toLowerCase().replace("_", "-")
- val upperCamelCase = name.split("_").map { it.toLowerCase().capitalize() }.joinToString("")
+ val kebabCase = name.lowercase().replace("_", "-")
+ val upperCamelCase = name.split("_").map { it.lowercase().capitalize() }.joinToString("")
}
diff --git a/tools/codegen/src/com/android/codegen/FileInfo.kt b/tools/codegen/src/com/android/codegen/FileInfo.kt
index cc3a15654956..ca04f1eb9ab7 100644
--- a/tools/codegen/src/com/android/codegen/FileInfo.kt
+++ b/tools/codegen/src/com/android/codegen/FileInfo.kt
@@ -126,7 +126,7 @@ class FileInfo(
+"\n}"
}
// Print general code as-is
- is CodeChunk.Code -> chunk.lines.forEach { stringBuilder.appendln(it) }
+ is CodeChunk.Code -> chunk.lines.forEach { stringBuilder.appendLine(it) }
// Recursively render data classes
is CodeChunk.DataClass -> chunk.chunks.forEach { print(it) }
}
@@ -175,11 +175,11 @@ class FileInfo(
/** Debug info */
override fun toString(): String {
return buildString {
- appendln("class $name $range")
+ appendLine("class $name $range")
nested.forEach {
- appendln(it)
+ appendLine(it)
}
- appendln("end $name")
+ appendLine("end $name")
}
}
}
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index d3a8b033dfff..710960249661 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -43,7 +43,7 @@ fun ClassPrinter.generateConstDef(consts: List<Pair<VariableDeclarator, FieldDec
}
var AnnotationName = prefix.split("_")
.filterNot { it.isBlank() }
- .map { it.toLowerCase().capitalize() }
+ .map { it.lowercase().capitalize() }
.joinToString("")
val annotatedConst = consts.find { it.second.annotations.isNonEmpty }
if (annotatedConst != null) {
@@ -122,7 +122,7 @@ fun FileInfo.generateAidl() {
if (aidl.exists()) return
aidl.writeText(buildString {
sourceLines.dropLastWhile { !it.startsWith("package ") }.forEach {
- appendln(it)
+ appendLine(it)
}
append("\nparcelable ${mainClass.nameAsString};\n")
})
diff --git a/tools/codegen/src/com/android/codegen/Utils.kt b/tools/codegen/src/com/android/codegen/Utils.kt
index a40bdd7ba8e1..96314435d1b7 100644
--- a/tools/codegen/src/com/android/codegen/Utils.kt
+++ b/tools/codegen/src/com/android/codegen/Utils.kt
@@ -62,7 +62,7 @@ fun String.toLowerCamel(): String {
if (length >= 2 && this[0] == 'm' && this[1].isUpperCase()) return substring(1).capitalize()
if (all { it.isLetterOrDigit() }) return decapitalize()
return split("[^a-zA-Z0-9]".toRegex())
- .map { it.toLowerCase().capitalize() }
+ .map { it.lowercase().capitalize() }
.joinToString("")
.decapitalize()
}
diff --git a/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
index 4995eebdd79e..fe72dae9ff34 100644
--- a/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
+++ b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
@@ -155,35 +155,35 @@ class IntDefProcessor : AbstractProcessor() {
) {
val indent = " "
- writer.appendln("{")
+ writer.appendLine("{")
val intDefTypesCount = annotationTypeToIntDefMapping.size
var currentIntDefTypesCount = 0
for ((field, intDefMapping) in annotationTypeToIntDefMapping) {
- writer.appendln("""$indent"$field": {""")
+ writer.appendLine("""$indent"$field": {""")
// Start IntDef
- writer.appendln("""$indent$indent"flag": ${intDefMapping.flag},""")
+ writer.appendLine("""$indent$indent"flag": ${intDefMapping.flag},""")
- writer.appendln("""$indent$indent"values": {""")
+ writer.appendLine("""$indent$indent"values": {""")
intDefMapping.entries.joinTo(writer, separator = ",\n") { (value, identifier) ->
"""$indent$indent$indent"$value": "$identifier""""
}
- writer.appendln()
- writer.appendln("$indent$indent}")
+ writer.appendLine()
+ writer.appendLine("$indent$indent}")
// End IntDef
writer.append("$indent}")
if (++currentIntDefTypesCount < intDefTypesCount) {
- writer.appendln(",")
+ writer.appendLine(",")
} else {
- writer.appendln("")
+ writer.appendLine("")
}
}
- writer.appendln("}")
+ writer.appendLine("}")
}
}
}